linux socket实现网络聊天室(二):使用线程独立收发消息

来源:互联网 发布:秦风拍牌软件好用吗 编辑:程序博客网 时间:2024/04/29 03:48

一、引言

二、代码实现

1、服务器端

/*tcpserver.c  2011.9.1 by yyg*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <pthread.h>#define MYPORT 3490  //定义端口#define BACKLOG 10#define MAXDATASIZE 1024int sockfd,new_fd;pthread_t accthread,recthread;void recmessage(void){  //接收客户端信息函数while(1){int numbytes;char buf[MAXDATASIZE];if((numbytes = recv(new_fd,buf,MAXDATASIZE,0))==-1){perror("recv");exit(1);}buf[numbytes]='\0';if(strcmp(buf,"exit")==0){  //若收到的是exit字符,则代表退出通信printf("Client is closed\n");close(new_fd);close(sockfd);exit(1);}printf("client:%s\n",buf);}/*while*/}void acceptconnect(void){  //接受客户端连接请求函数struct sockaddr_in their_addr;int sin_size;sin_size = sizeof(struct sockaddr_in);if((new_fd = accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1){perror("accept");exit(1);}printf("server:got connection from %s\n",inet_ntoa(their_addr.sin_addr));/*创建子线程,用于接收信息*/if((pthread_create(&recthread,NULL,(void*)recmessage,NULL)) != 0){printf("create thread error!\r\n");exit(1);}}int main(void){struct sockaddr_in my_addr;/*创建套接字*/if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");exit(1);}/*初始化sockaddr_in结构体相关参数*/my_addr.sin_family = AF_INET;my_addr.sin_port = htons(MYPORT);my_addr.sin_addr.s_addr = INADDR_ANY;bzero(&(my_addr.sin_zero),8);/*绑定端口与套接字*/if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr)) == -1){perror("bind");exit(1);}/*监听客户端套接字*/if(listen(sockfd,BACKLOG)== -1){perror("listen");exit(1);}printf("listening...\n");/*创建子线程,用于接收信息*/if((pthread_create(&accthread,NULL,(void*)acceptconnect,NULL))!=0){printf("create thread error!\n");exit(1);}while(1){char msg[MAXDATASIZE];scanf("%s",msg);if(send(new_fd,msg,strlen(msg),0) == -1){  //发送信息,与客户端交流perror("send");exit(1);}if(strcmp(msg,"exit") ==0){printf("byebye\n");close(new_fd);close(sockfd);exit(1);}}/*while*/return 0;}/*main*/

2.客户端

/*tcpclient.c    2010.9.1 by yyg*/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <sys/wait.h>#include <pthread.h>#include <netdb.h>#define PORT 3490#define BACKLOG 10#define MAXDATASIZE 1024int sockfd;pthread_t recthread;/*接收信息函数*/void recmessage(void){while(1){int numbytes;char buf[MAXDATASIZE];if((numbytes = recv(sockfd,buf,MAXDATASIZE,0))==-1){perror("recv");exit(1);}buf[numbytes]='\0';if(strcmp(buf,"exit")==0){printf("Server is closed\n");close(sockfd);exit(1);}printf("Server:%s\n",buf);}/*while*/}int main(int argc,char *argv[]){struct hostent *he;struct sockaddr_in their_addr;/*客户端输入方式:./client 172.31.100.236,若无输入后面IP地址,会提示错误*/if(argc != 2){fprintf(stderr,"usage:client hostname\n");exit(1);}/*获取主机IP地址*/if((he = gethostbyname(argv[1])) == NULL){herror("gethostbyname");exit(1);}/*创建套接字*/if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");exit(1);}/*初始化sockaddr_in结构体*/their_addr.sin_family = AF_INET;their_addr.sin_port = htons(PORT);their_addr.sin_addr = *((struct in_addr *)he->h_addr);bzero(&(their_addr.sin_zero),8);/*向服务器发送连接请求*/if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr)) == -1){perror("connect");exit(1);}/*创建子线程,用于接收信息*/if((pthread_create(&recthread,NULL,(void*)recmessage,NULL))!= 0){printf("create thread error!\r\n");exit(1);}/*发送信息。接收发送信息用的是同一端口,都 是sockfd*/while(1){char msg[MAXDATASIZE];scanf("%s",msg);if(send(sockfd,msg,strlen(msg),0) == -1){perror("send");exit(1);}if(strcmp(msg,"exit") ==0){printf("byebye\n");close(sockfd);exit(1);}}/*while*/return 0;}

运行结果:

终端1:

[root@localhost net]# ./tcpserverserver:got connection from 172.31.100.236Hello,World! client:helloclient:xiaolianclient:iouokexitbyebye

终端2:

[root@localhost net]# ./tcpclient 172.31.100.236Server:Hello,World!helloxiaolian iouServer:okServer is closed

 

 

 

原创粉丝点击