先联想一下聊天的场景,假设甲和乙在聊天,他们每个人都能够发送给对方一句话甚至多句话,也能接收到对方发来的一句或多句话,也就是说,甲在发送一句话给乙的时候,同时也能接收到乙发来的信息,而且甲还能连续发多条信息,对于乙来说也是一样。这也就是说程序当中必须要有两个执行流,一个用于发信息,一个用于接受信息。
服务器
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <arpa/inet.h>pthread_t r_tid=0,w_tid=0;void *do_read(void *client_sockid_)
{int client_sockid=*((int *)client_sockid_);char send[100]={0};while(1){fgets(send,sizeof(send),stdin);if(strcmp(send,"NULL\n")==0){printf("您已下线\n");break;}write(client_sockid,send,sizeof(send));memset(send,0,strlen(send));}pthread_cancel(w_tid);//结束发送操作线程
}void *do_write(void *client_sockid_)
{int client_sockid=*((int *)client_sockid_);char receive[100]={0};while(1){if(!read(client_sockid,receive,sizeof(receive))){printf("对方已下线,已退出\n");break;}printf("\t\t\t");fputs(receive,stdout);memset(receive,0,sizeof(receive));}pthread_cancel(r_tid);//结束接收操作线程
}int internet()
{struct sockaddr_in sockaddr;sockaddr.sin_family=AF_INET;sockaddr.sin_port=htons(5188);sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);int sockid=socket(AF_INET,SOCK_STREAM,0);const int on=1;if(setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0){printf("setsockopt\n");return 0;}if(bind(sockid,(struct sockaddr *)&sockaddr,sizeof(sockaddr))<0){printf("bind\n");return 0;}if(listen(sockid,SOMAXCONN)<0){printf("listen\n");return 0;}struct sockaddr_in other_sock_addr;socklen_t other_sock_addr_len=sizeof(other_sock_addr);pid_t pid=0;int client_sockid=0;client_sockid=accept(sockid,(struct sockaddr *)&other_sock_addr,&other_sock_addr_len);printf("ip=%s,port=%d\n",inet_ntoa(other_sock_addr.sin_addr),ntohs(other_sock_addr.sin_port));if(client_sockid<0){printf("accept\n");return 0;}pthread_create(&r_tid,NULL,do_read,(void *)&client_sockid);pthread_create(&w_tid,NULL,do_write,(void *)&client_sockid);pthread_join(r_tid,NULL);pthread_join(w_tid,NULL);close(sockid);close(client_sockid);
}int main()
{internet();return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>pthread_t r_tid=0,w_tid=0;void *do_read(void *sockid_)
{int sockid=*((int *)sockid_);char send[100]={0};while(1){fgets(send,sizeof(send),stdin);if(strcmp(send,"NULL\n")==0){printf("您已下线\n");break;}write(sockid,send,sizeof(send));memset(send,0,strlen(send));}pthread_cancel(w_tid);//结束发送操作线程
}void *do_write(void *sockid_)
{int sockid=*((int *)sockid_);char receive[100]={0};while(1){if(!read(sockid,receive,sizeof(receive))){printf("对方已下线,即将退出\n");break;}printf("\t\t\t");fputs(receive,stdout);memset(receive,0,sizeof(receive));}pthread_cancel(r_tid);//结束接收操作进程
}int internet()
{struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(5188);addr.sin_addr.s_addr=inet_addr("127.0.0.1");int sockid=socket(AF_INET,SOCK_STREAM,0);socklen_t addrlen=sizeof(addr);if(connect(sockid,(struct sockaddr *)&addr,addrlen)<0){printf("connect\n");return 0;}pthread_create(&r_tid,NULL,do_read,(void *)&sockid);pthread_create(&w_tid,NULL,do_write,(void *)&sockid);pthread_join(r_tid,NULL);pthread_join(w_tid,NULL);close(sockid);return 0;
}int main()
{internet();return 0;
}
以上程序只能在局域网内通信。实现跨局域网聊天请点击