Linux网络编程学习笔记-简单点对点聊天程序--6
来源:互联网 发布:超融合软件下载 编辑:程序博客网 时间:2024/04/29 20:52
服务器端套接字分两种,一种是监听套接字,一个是已连接套接字。客户端只有已连接套接字。
监听套接字主要用来接受三次握手数据,一旦三次握手完成了,那么就将其放到已连接队列中,accpet()就可以从中返回一个连接,返回的这个连接被称之为已连接套接字,是用来和客户端进行通信的,并不能接受连接,为主动套接字。
因此一个服务器端有3个客户机连接时,服务器端就有3个不同的已连接套接字,1个监听套接字。
下面是点对点聊天程序的实现:
/*服务器端程序*/#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/shm.h>#define MYPORT 8887#define QUEUE 20#define BUFFER_SIZE 1024#define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0)int do_service(int conn){ char recvbuf[BUFFER_SIZE]={0}; memset(recvbuf,0,sizeof(recvbuf)); int length = recv(conn,recvbuf,sizeof(recvbuf),0); if(length == 0){//客户端关闭的情况 //signal(SIGUSR1,handler); printf("client close by accient\n"); return 0; } if(length < 0){ //如果失败 ERR_EXIT("recv"); return 0; } if(strcmp(recvbuf,"exit\n")==0) return 0; else{ fputs(recvbuf,stdout); return 1; } }int main(){ //定义客户端套接字 int sock_ser = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//最后一位可为0,自动 if(sock_ser <0)//如果失败 ERR_EXIT("socket"); //定义sockaddr_in struct sockaddr_in addr_ser; addr_ser.sin_family = AF_INET; addr_ser.sin_port = htons(MYPORT); addr_ser.sin_addr.s_addr = htonl(INADDR_ANY); //开启地址重复利用 int on = 1; int rel_set = setsockopt(sock_ser,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); if(rel_set < 0)//如果失败 ERR_EXIT("reuseaddr"); //bind 绑定 int bd = bind(sock_ser,(struct sockaddr*)&addr_ser,sizeof(addr_ser)); if(bd < 0)//如果失败 ERR_EXIT("bind"); //listen 监听 int ln = listen(sock_ser,SOMAXCONN);//listen函数将套接字从主动套接字变成被动套接字;主动套接字主要用来发起连接,而被动套接字用来接受连接 //第二个参数规定能够并发连接的最大数目 =未完成连接数目+ 已完成连接数目: if(ln < 0) //如果错误 ERR_EXIT("listen"); /* 开始定义客户端套接字 */ struct sockaddr_in addr_cli; socklen_t len = sizeof(addr_cli); //使用进程处理多并发 pid_t pid; while(1){ //accept 接收 int conn = accept(sock_ser,(struct sockaddr*)&addr_cli,&len); printf("ip=%s,port=%d\n",inet_ntoa(addr_cli.sin_addr),ntohs(addr_cli.sin_port));//新增打印通信ip和端口 if(conn < 0) //如果失败 ERR_EXIT("accept"); //创建父进程--发送数据 pid = fork(); if(pid == -1) ERR_EXIT("fork"); if(pid == 0)//创建成功 { char sendbuf[BUFFER_SIZE]={0}; while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL){ send(conn,sendbuf,sizeof(sendbuf),0); memset(sendbuf,0,sizeof(sendbuf)); } printf("child close \n"); exit(EXIT_SUCCESS); close(conn); } else { while(do_service(conn)); printf("parent close\n"); exit(EXIT_SUCCESS); close(conn); } } return 0;}
#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <fcntl.h>#include <sys/shm.h>#include <signal.h>#define MYPORT 8887#define BUFFER_SIZE 1024#define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0)void handler(int sig){ printf("recv a signal =%d\n",sig); exit(EXIT_SUCCESS); }int main(){ //定义客户端socket int sock_cli = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sock_cli < 0 )//如果失败 ERR_EXIT("socket"); //定义sockaddr struct sockaddr_in addr_cli; addr_cli.sin_family = AF_INET; addr_cli.sin_port = htons(MYPORT); addr_cli.sin_addr.s_addr = inet_addr("127.0.0.1"); int conn = connect(sock_cli,(struct sockaddr*)&addr_cli,sizeof(addr_cli)); if(conn < 0) ERR_EXIT("connect"); char recvbuf[BUFFER_SIZE]={0}; char sendbuf[BUFFER_SIZE]={0}; pid_t pid; pid = fork(); if(pid == -1) ERR_EXIT("fork"); if(pid == 0)//发送数据 { while(1){ memset(recvbuf,0,sizeof(recvbuf)); int length = recv(sock_cli,recvbuf,sizeof(recvbuf),0); if(length <0) ERR_EXIT("recv"); else if(length == 0){ printf("peer close\n"); break; } fputs(recvbuf,stdout); } close(conn); kill(getppid(),SIGUSR1); } else { while(fgets(sendbuf,sizeof(sendbuf),stdin)!=0){ send(sock_cli,sendbuf,sizeof(sendbuf),0);//发送 memset(sendbuf,0,sizeof(sendbuf)); } } close(conn); return 0; }
0 0
- Linux网络编程学习笔记-简单点对点聊天程序--6
- Linux网络编程之简易的点对点聊天程序程序
- 网络编程中简单的点对点聊天程序
- LINUX网络编程,简单的聊天程序
- c#网络编程学习笔记02_Tcp编程(中)_简单的同步tcp聊天程序
- MFC实现简单点对点聊天程序
- socket编程之点对点聊天程序
- 点对点聊天程序
- 设计点对点聊天程序
- netty 点对点聊天程序
- iPhone网络编程初体验-简单的聊天程序(适合新手学习客户端服务器交互)
- Unix网络编程之点对点聊天-客户端与服务器实现
- VB 利用UDP制作简单的点对点聊天程序
- 网络编程学习笔记(二)UDP协议及聊天小程序的实现
- iPhone网络编程初体验-简单的聊天程序
- iPhone之网络编程初体验-简单的聊天程序
- iPhone网络编程初体验-简单的聊天程序
- JAVA网络编程——简单的聊天程序
- Codeforces 781B 二分图
- BZOJ 2595 [Wc2008]游览计划 SPFA+斯坦纳树 or 插头DP
- 单链表中是否有环
- 编写一个简单的内核模块程序Hello World!
- 关于预测
- Linux网络编程学习笔记-简单点对点聊天程序--6
- 安全体系(零)—— 加解密算法、消息摘要、消息认证技术、数字签名与公钥证书
- HDU 3333 线段树+离散化
- Codeforces Round #180 (Div. 2) B. Sail 【模拟】
- 回到顶部实现
- WEB即时通讯/消息推送
- Linux vi 使用方法
- 隐藏滚动条、保留鼠标滚动效果
- ART运行时之method/field加载