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网络编程--聊天程序(2)相关推荐
- Socket网络编程--聊天程序(8)
上一节已经完成了对用户的身份验证了,既然有了验证,那么接下来就能对不同的客户端进行区分了,所以这一节讲实现私聊功能.就是通过服务器对客户端的数据进行转发到特定的用户上, 实现私聊功能的聊天程序 实现的 ...
- Socket网络编程--聊天程序(3)
上一小节,已经讲到可以每个人多说话,而且还没有限制,简单的来说,我们已经完成了聊天的功能了,那么接下来我们要实现什么功能呢?一个聊天程序至少应该支持一对多的通讯吧,接下来就实现多个客户端往服务器发送数 ...
- 基于Udp的Socket网络编程聊天程序
1.新建一个工程区Net 在工作区中添加两个工程 NetSrv 和 NetClient 为两个工程添加库文件 (Link中) ws2_32.lib 2.在工程NetSrv中添加Server.cpp文件 ...
- Socket网络编程--小小网盘程序(5)
http://www.cnblogs.com/wunaozai/p/3893469.html 各位好呀!这一小节应该就是这个小小网盘程序的最后一小节了,这一节将实现最后的三个功能,即列出用户在服务器中 ...
- Socket网络编程(2)--服务端实现
中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...
- MFC socket网络编程(流程示例)
MFC socket网络编程(流程示例) 1.TCP流式套接字的编程步骤 在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib,OK! 服务器端程序: 1.加 ...
- Netty网络编程聊天项目
Netty网络编程聊天项目 后端编写 导入依赖 <dependencies><dependency>&l ...
- BIO,Socket网络编程入门代码示例,NIO网络编程入门代码示例,AIO 网络编程
BIO,Socket网络编程入门代码示例 1.BIO服务器端程序 package cn.itcast.bio;import java.io.InputStream; import java.io.Ou ...
- python网络编程讲解_详解Python Socket网络编程
Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...
最新文章
- 通过js引入当前所需要的js,css等
- iphone分辨率_目前最值得入手的三款安卓机!流畅度堪比iPhone,用三五年不过时...
- 【明星自动大变脸】最新StarGAN对抗生成网络实现多领域图像变换(附代码)
- Java里optionsMenu.add_NoActionBar主题下如何添加OptionsMenu
- SQL比oracle卡,对比Oracle与SQL Server
- excel几个表合成一张_Excel中怎样把多张表格中的数据合并到一张表格中
- Python版的百钱买百鸡问题
- 快速排序算法_大佬的快速排序算法,果然不一样
- React Router 全部
- Kotlin | Kotlin教程
- html中 DPlayer 播放m3u8文件【方式二】
- iPhone Xs和iPhoneXs max 的区别 哪个好
- 手把手指导制作一个 WebAR 与小程序 AR
- 红孩儿编辑器的详细设计第四部分
- 影响stable diffusion的embedding训练效率的部分问题和拟解决办法
- 丰巢科技面试题(2019年JAVA)
- 06-初始OpenGL ES -用GLSL实现画板的功能
- Docker构建Mycat
- C语言实现空心金字塔输出
- 手机app出现问题,如何定位?