Linux下实现类似QQ的通信(简单聊天程序)

来源:互联网 发布:猎枪缩口数据 编辑:程序博客网 时间:2024/05/16 06:10

这几天在弄有关Linux下实现socket通信方面的东西,发现了一段比较好的代码,用于实现简单聊天的程序。


服务器端代码分析:

服务器端流程如下:

(1)根据用户命令行输入,设置欲绑定的IP地址、端口以及listen队列大小

(2)创建基于IPV4的数据流方式socket对象

(3)绑定IP地址,监听网络,等待客户端连接

(4)先阻塞等待终端输入数据,如果接收到数据,将数据发送到客户端,然后再结束socket消息,等待客户端数据,如果接收到数据,打印到终端。完成后继续循环

以下是服务器端的代码内容:

#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<unistd.h>#include<arpa/inet.h>#define MAXBUF 1024int main(int argc,char *argv[]){int pid;int sockfd,new_fd;socklen_t len;struct sockaddr_in my_addr,their_addr;unsigned int myport,lisnum;char buf[MAXBUF+1];if(argv[2])myport=atoi(argv[2]);elsemyport=7575;if(argv[3])lisnum=atoi(argv[3]);elselisnum=5;if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){perror("socket");exit(EXIT_FAILURE);}bzero(&my_addr,sizeof(my_addr));my_addr.sin_family=AF_INET;my_addr.sin_port=htons(myport);if(argv[1])my_addr.sin_addr.s_addr=inet_addr(argv[1]);elsemy_addr.sin_addr.s_addr=INADDR_ANY;if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){perror("bind");exit(EXIT_FAILURE);}if(listen(sockfd,lisnum)==-1){perror("listen");exit(EXIT_FAILURE);}printf("wait for connect!\n");len=sizeof(struct sockaddr);if((new_fd=accept(sockfd,(struct sockaddr *)&their_addr,&len))==-1){perror("accept");exit(EXIT_FAILURE);}elseprintf("server:got connection from %s,port %d,socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port),new_fd);while(1){printf("newfd=%d\n",new_fd);bzero(buf,MAXBUF+1);printf("input the message to send:");fgets(buf,MAXBUF,stdin);if(!strncasecmp(buf,"quit",4)){printf("i will close the connect!\n");break;}len=send(new_fd,buf,strlen(buf)-1,0);if(len>0)printf("message:%s\t send sucessful,send %dbyte!\n",buf,len);else{printf("message'%s' send failure!errno code is %d,errno message is '%s'\n",buf,errno,strerror(errno));break;}bzero(buf,MAXBUF+1);len=recv(new_fd,buf,MAXBUF,0);if(len>0)printf("message recv successful:'%s',%dByte recv\n",buf,len);else{if(len<0)printf("recv failure!errno code is %d,errno message is '%s'\n",errno,strerror(errno));elseprintf("the other one close quit\n");break;}}close(new_fd);close(sockfd);return 0;}

客户器端代码分析:

客户器端流程如下:

(1)根据用户命令行输入,设置欲连接的服务IP地址、端口

(2)创建基于IPV4的数据流方式socket对象

(3)向服务器端发起连接

(4)先阻塞等待服务器端数据,如果接收到数据,打印该数据,然后再阻塞于终端,等待终端输入数据,然后发出数据到服务端。完成后继续循环

#include<stdio.h>#include<string.h>#include<errno.h>#include<sys/socket.h>#include<resolv.h>#include<stdlib.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#define MAXBUF 1024int main(int argc,char **argv){int sockfd,len;struct sockaddr_in dest;char buffer[MAXBUF+1];if(argc!=3){printf("error format,it must be:\n\t\t%s IP port\n",argv[0]);exit(EXIT_FAILURE);}if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){perror("Socket");exit(errno);}printf("socket created\n");bzero(&dest,sizeof(dest));dest.sin_family=AF_INET;dest.sin_port=htons(atoi(argv[2]));if(inet_aton(argv[1],(struct in_addr *)&dest.sin_addr.s_addr)==0){perror(argv[1]);exit(errno);}if(connect(sockfd,(struct sockaddr *)&dest,sizeof(dest))==-1){perror("Connect");exit(errno);}printf("server connected\n");while(1){bzero(buffer,MAXBUF+1);len=recv(sockfd,buffer,MAXBUF,0);if(len>0)printf("recv successful:'%s',%d byte recv\n",buffer,len);else{if(len<0)printf("send failure,errno code is %d,err message is '%s'\n",errno,strerror(errno));elseprintf("the other one close,quit\n");break;}bzero(buffer,MAXBUF+1);printf("pls send message to send:");fgets(buffer,MAXBUF,stdin);if(!strncasecmp(buffer,"quit",4)){printf("i will quit!\n");break;}len=send(sockfd,buffer,strlen(buffer)-1,0);if(len<0){printf("message '%s' send failure,errno code is %d,errno message is '%s'\n",buffer,errno,strerror(errno));break;}elseprintf("message:%s\tsend successful,%dbyte send!\n",buffer,len);}close(sockfd);return 0;}



0 0
原创粉丝点击