博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket网络编程--聊天程序(2)
阅读量:5265 次
发布时间:2019-06-14

本文共 4827 字,大约阅读时间需要 16 分钟。

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

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

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

  fork函数

  #include <unistd.h>

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

  client.c

1 #include 
2 #include
3 #include
4 #include
5 #include
//for gethostbyname 6 #include
7 #include
8 #include
9 #include
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 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
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 }

 

 

  本文地址: 

转载于:https://www.cnblogs.com/wunaozai/p/3870194.html

你可能感兴趣的文章
Shell操作相关的快捷键 --Linux
查看>>
LC-456 132模式
查看>>
中文编码问题
查看>>
简单makefile的写法
查看>>
javascript正则多次调用test 结果交替出现
查看>>
How Django works?
查看>>
程序设计原则——LSP
查看>>
【转】c#实现文件下载
查看>>
mysqldump指令说明
查看>>
sql server面试题
查看>>
ogg数据初始化历程记录
查看>>
VFP通用代码(vcx/scx/prg)混淆器,可以下载了
查看>>
QGhappy第二次例会(任务分配)
查看>>
前端学习回顾
查看>>
python json.dumps 中的ensure_ascii 参数引起的中文编码问题
查看>>
Python中利用原始套接字进行网络编程的示例
查看>>
Python使用numpy实现BP神经网络
查看>>
反射常用API
查看>>
Java多线程-线程的调度(守护线程)
查看>>
NO.9章 树(遍历、BST、AVL、并查集、堆、哈夫曼)
查看>>