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 4096

12 #define SERVER_PORT 12138

13 

14 

15 int main(int argc,char *argv[])

16 {

17     int sockfd;//socket

18     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     //创建socket

43     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.c

65     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     else

79     {

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     else

100     {

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)