Linux IPC tcp/ip socket 编程(2)

sockfd: 用于通信的socket描述符(returned by accept())
buf: 接收数据的缓冲区首地址
len: 接收数据的大小
flags: 发送的标志, 如果给0等同于read()

connect(): //初始化一个socket的连接,用在客户端,成功返回0,失败返回-1设errno int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: socket文件的fd(returned by socket())
addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
addrlen: 通信地址的大小, 使用sizeof();

例子-多进程并发tcp/ip协议服务器模型

除了这种多进程的并发模型,还有多线程并发和I/O多路复用并发等方式

//创建server, 用多进程同时响应多个client的请求, 当client发来 “bye”的时候断开连接, 按下Ctrl+C关闭服务器 #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> //省略了几个头文件 int sockfd; //全局变量 void fa(int signo){ printf("closing server...\n"); sleep(3); int res=close(sockfd); if(-1==res) perror("close"),exit(-1); printf("server closed\n"); exit(0); } int main(){ … //同上一个程序 //set SIGINT printf("Press ctrl+c to close server\n"); if(SIG_ERR==signal(SIGINT,fa)) //整个程序,包括第一个while(1)是通过信号处理终止的 perror("signal"),exit(-1); while(1){ //只要有client接入就创建新进程与之通信 struct sockaddr_in recv_addr; socklen_t len=sizeof(recv_addr); int CnnSockfd=accept(sockfd,(struct sockaddr*)&recv_addr,&len); //如果侦听队列里面有client就accept(), 否则就在这阻塞着,不继续执行,除非遇到Ctrl+C终止整个进程 if(-1==CnnSockfd) perror("accept"),exit(-1); char *ip=inet_ntoa(recv_addr.sin_addr); printf("client:%s linked\n",ip); pid_t pid=fork(); if(-1==pid) perror("fork()"),exit(-1); if(0==pid){ if(SIG_ERR==signal(SIGINT,SIG_DFL)) perror("signal"),exit(-1); //每个child处理一个client,所以已经不需要listening socket了,可以把它关了 //如果不关子进程也会有一个listenfd,会和父进程一起抢,不应该 res=close(sockfd); if(-1==res) perror("close"),exit(-1); while(1){ //只要client发数据就处理,除非遇到 “bye” char buf[100]={0}; res=recv(CnnSockfd,buf,sizeof(buf),0); if(-1==res) perror("recv"),exit(-1); printf("client%s,data sent:%s\n",ip,buf); if(!strcmp(buf,"bye")){ //遇到“bye”就不再待命,break掉准备断开连接 printf("client%s has been unlinked\n",ip); break; } res=send(CnnSockfd,"I received!",12,0); if(-1==res) perror("send"),exit(-1); } res=close(CnnSockfd); //断开连接即close(相应的connected socket) if(-1== res) perror("close"),exit(-1); exit(0); //断开了连接了,就可以exit子进程了 } res=close(CnnSockfd); // if(-1==res) perror("close"),exit(-1); } return 0; }

本文永久更新链接地址

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c58249b3e2ee611f5ddda10dfa82eace.html