上一节简单如何通过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网络编程--聊天程序(2)相关推荐

  1. Socket网络编程--聊天程序(8)

    上一节已经完成了对用户的身份验证了,既然有了验证,那么接下来就能对不同的客户端进行区分了,所以这一节讲实现私聊功能.就是通过服务器对客户端的数据进行转发到特定的用户上, 实现私聊功能的聊天程序 实现的 ...

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

    上一小节,已经讲到可以每个人多说话,而且还没有限制,简单的来说,我们已经完成了聊天的功能了,那么接下来我们要实现什么功能呢?一个聊天程序至少应该支持一对多的通讯吧,接下来就实现多个客户端往服务器发送数 ...

  3. 基于Udp的Socket网络编程聊天程序

    1.新建一个工程区Net 在工作区中添加两个工程 NetSrv 和 NetClient 为两个工程添加库文件 (Link中) ws2_32.lib 2.在工程NetSrv中添加Server.cpp文件 ...

  4. Socket网络编程--小小网盘程序(5)

    http://www.cnblogs.com/wunaozai/p/3893469.html 各位好呀!这一小节应该就是这个小小网盘程序的最后一小节了,这一节将实现最后的三个功能,即列出用户在服务器中 ...

  5. Socket网络编程(2)--服务端实现

    中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...

  6. MFC socket网络编程(流程示例)

    MFC socket网络编程(流程示例) 1.TCP流式套接字的编程步骤 在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib,OK! 服务器端程序: 1.加 ...

  7. Netty网络编程聊天项目

                                     Netty网络编程聊天项目 后端编写 导入依赖    <dependencies><dependency>&l ...

  8. BIO,Socket网络编程入门代码示例,NIO网络编程入门代码示例,AIO 网络编程

    BIO,Socket网络编程入门代码示例 1.BIO服务器端程序 package cn.itcast.bio;import java.io.InputStream; import java.io.Ou ...

  9. python网络编程讲解_详解Python Socket网络编程

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

最新文章

  1. 通过js引入当前所需要的js,css等
  2. iphone分辨率_目前最值得入手的三款安卓机!流畅度堪比iPhone,用三五年不过时...
  3. 【明星自动大变脸】最新StarGAN对抗生成网络实现多领域图像变换(附代码)
  4. Java里optionsMenu.add_NoActionBar主题下如何添加OptionsMenu
  5. SQL比oracle卡,对比Oracle与SQL Server
  6. excel几个表合成一张_Excel中怎样把多张表格中的数据合并到一张表格中
  7. Python版的百钱买百鸡问题
  8. 快速排序算法_大佬的快速排序算法,果然不一样
  9. React Router 全部
  10. Kotlin | Kotlin教程
  11. html中 DPlayer 播放m3u8文件【方式二】
  12. iPhone Xs和iPhoneXs max 的区别 哪个好
  13. 手把手指导制作一个 WebAR 与小程序 AR
  14. 红孩儿编辑器的详细设计第四部分
  15. 影响stable diffusion的embedding训练效率的部分问题和拟解决办法
  16. 丰巢科技面试题(2019年JAVA)
  17. 06-初始OpenGL ES -用GLSL实现画板的功能
  18. Docker构建Mycat
  19. C语言实现空心金字塔输出
  20. 手机app出现问题,如何定位?

热门文章

  1. 3.3 其他因素3.3.1 Fork子进程
  2. SQL Server 日期函数:EOMonth、DateFormat、Format、DatePart、DateName
  3. PHP laravel框架Redis门面的误用
  4. mysql数据库配置优化(占cpu过高问题)
  5. 将本地数据库备份到远程服务器
  6. Linux发展历史图
  7. 用JS实现自动提取身份证的出生日期
  8. 大型云原生项目在数字化企业落地过程解密 1
  9. Laravel 深入核心系列教程
  10. 编写一个头像裁剪组件(一)