首页 > 代码库 > Socket网络编程--聊天程序(2)

Socket网络编程--聊天程序(2)

  上一节简单如何通过Socket创建一个连接,然后进行通信。只是每个人只能说一句话。而且还是必须说完才会接收到信息,总之是很不方便的事情。所以这一小节我们将对上一次的程序进行修改,修改成每个人可以多说话,主要是通过Linux下多进程fork实现的。

  一对一,server和client是每个人都可以多说几句话

  由于控制台度数据的函数fgets是阻塞函数,要每个人都可以多说话,这里我使用的是读取和发送都在不同的进程里面,使之互相没有影响。

  fork函数

  #include <unistd.h>

  pid_t fork(void);    //返回值:子进程中返回0,父进程中返回子进程ID,出错返回-1

  client.c

 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <string.h> 5 #include <netdb.h> //for gethostbyname 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h>10 11 #define MAX_BUF 409612 #define SERVER_PORT 1213813 14 15 int main(int argc,char *argv[])16 {17     int sockfd;//socket18     char sendBuf[MAX_BUF],recvBuf[MAX_BUF];19     int sendSize,recvSize;//用于记录记录发送和接收到数据的大小20     struct hostent * host;21     struct sockaddr_in servAddr;22     char username[32];23     char * p;24     int pid;25 26     if(argc != 3)27     {28         perror("use: ./client [hostname] [username]");29         exit(-1);30     }31     p=username;32     strcpy(p,argv[2]);33     printf("username:%s\n",username);34     host=gethostbyname(argv[1]);35     if(host==NULL)36     {37         perror("fail to get host by name.");38         exit(-1);39     }40     printf("Success to get host by name ...\n");41 42     //创建socket43     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)44     {45         perror("fail to establish a socket");46         exit(1);47     }48     printf("Success to establish a socket...\n");49 50     /*init sockaddr_in*/51     servAddr.sin_family=AF_INET;52     servAddr.sin_port=htons(SERVER_PORT);53     servAddr.sin_addr=*((struct in_addr *)host->h_addr);54     bzero(&(servAddr.sin_zero),8);55 56     /*connect the socket*/57     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)58     {59         perror("fail to connect the socket");60         exit(1);61     }62     printf("Success to connect the socket...\n");63 64     //send-recv 一些返回指没有判断,具体可以看server.c65     if((pid=fork())<0)66     {67         perror("fork error\n");68     }69     else if(pid>0)/*child*/70     {71         while(1)72         {73             fgets(sendBuf,MAX_BUF,stdin);74             send(sockfd,sendBuf,strlen(sendBuf),0);75             memset(sendBuf,0,sizeof(sendBuf));76         }77     }78     else79     {80         while(1)81         {82             recv(sockfd,recvBuf,MAX_BUF,0);83             printf("Server:%s\n",recvBuf);84             memset(recvBuf,0,sizeof(recvBuf));85         }86     }87 88     return 0;89 }

  server.c

  1 #include <stdio.h>  2 #include <stdlib.h>  3 #include <errno.h>  4 #include <string.h>  5 #include <netdb.h>  6 #include <sys/types.h>  7 #include <sys/socket.h>  8 #include <sys/time.h>  9 #include <sys/un.h> 10 #include <sys/ioctl.h> 11 #include <sys/wait.h> 12 #include <netinet/in.h> 13 #include <arpa/inet.h> 14  15  16 #define SERVER_PORT 12138 17 #define BACKLOG 20 18 #define MAX_CON_NO 10 19 #define MAX_DATA_SIZE 4096 20  21 int main(int argc,char *argv[]) 22 { 23     struct sockaddr_in serverSockaddr,clientSockaddr; 24     char sendBuf[MAX_DATA_SIZE],recvBuf[MAX_DATA_SIZE]; 25     int sendSize,recvSize; 26     int sockfd,clientfd; 27     int on=1; 28     int sinSize=0; 29     char username[32]; 30     int pid; 31  32     if(argc != 2) 33     { 34         printf("usage: ./server [username]\n"); 35         exit(1); 36     } 37     strcpy(username,argv[1]); 38     printf("username:%s\n",username); 39  40     /*establish a socket*/ 41     if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) 42     { 43         perror("fail to establish a socket"); 44         exit(1); 45     } 46     printf("Success to establish a socket...\n"); 47  48     /*init sockaddr_in*/ 49     serverSockaddr.sin_family=AF_INET; 50     serverSockaddr.sin_port=htons(SERVER_PORT); 51     serverSockaddr.sin_addr.s_addr=htonl(INADDR_ANY); 52     bzero(&(serverSockaddr.sin_zero),8); 53  54     setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); 55  56     /*bind socket*/ 57     if(bind(sockfd,(struct sockaddr *)&serverSockaddr,sizeof(struct sockaddr))==-1) 58     { 59         perror("fail to bind"); 60         exit(1); 61     } 62     printf("Success to bind the socket...\n"); 63  64     /*listen on the socket*/ 65     if(listen(sockfd,BACKLOG)==-1) 66     { 67         perror("fail to listen"); 68         exit(1); 69     } 70  71     /*accept a client‘s request*/  //这里的sinSize还没有处理,具体看下一节 72     if((clientfd=accept(sockfd,(struct sockaddr  *)&clientSockaddr, &sinSize))==-1)  73     { 74         perror("fail to accept"); 75         exit(1); 76     } 77     printf("Success to accpet a connection request...\n"); 78     printf(" %s join in!\n",inet_ntoa(clientSockaddr.sin_addr)); 79  80     if((pid=fork())<0) 81     { 82         perror("fork error\n"); 83     } 84     else if(pid>0)/*child*/ 85     { 86         /*send datas to client*/ 87         while(1) 88         { 89             fgets(sendBuf,MAX_DATA_SIZE,stdin); 90             if((sendSize=send(clientfd,sendBuf,strlen(sendBuf),0))!=strlen(sendBuf)) 91             { 92                 perror("fail to send datas"); 93                 exit(1); 94             } 95             printf("Success to send datas\n"); 96             memset(sendBuf,0,MAX_DATA_SIZE); 97         } 98     } 99     else100     {101         while(1)102         {103             /*receive datas from client*/104             if((recvSize=recv(clientfd,recvBuf,MAX_DATA_SIZE,0))==-1)105             {106                 perror("fail to receive datas");107                 exit(1);108             }109             printf("Client:%s\n",recvBuf);110             memset(recvBuf,0,MAX_DATA_SIZE);111         }112 113     }114 115     return 0;116 }

 

 

  本文地址: http://www.cnblogs.com/wunaozai/p/3870194.html

Socket网络编程--聊天程序(2)