- 1、流程
- 2、代码
需求:将客户端发送过来的数据,转换成大写,并将大写回过去
参考:
Linux c socket套接字(看完测底明白六大函数使用)
Linux c 通过信号回收N个子进程
1、socket 创建监听套接字 2、bind 绑定地址结构 3、lisen 链接上限 4、创建子进程 子进程: 4.1 关闭用于建立连接的文件描述符(使用不到) 4.2 读 4.3 将读到的内容改写成小写 4.4 写给客户端 4.5 循环此过程,当read读到的数据为0时表示客户端已断开 4.6 关闭通信文件描述符 父进程: 注册信号函数,回收子进程 关闭通信文件描述符(父进程使用不到) 循环到上面,阻塞在accept函数上继续等待客户端建立建立2、代码
开头首字母大写的网络通信函数,只是进行了一道浅封装,没有多东西
服务端
#include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "socket_wrap.h" void catch_child(int signum) { while(waitpid(0,NULL,WNOHANG)>0); return; } int main() { int fd,cfd; fd = Socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in str_in,cstr_in; bzero(&str_in,sizeof(str_in)); str_in.sin_family = AF_INET; str_in.sin_port = htons(9999); str_in.sin_addr.s_addr = htonl(INADDR_ANY); Bind(fd,(struct sockaddr*)&str_in,sizeof(str_in)); Listen(fd,128); socklen_t cst_len = sizeof(cstr_in); pid_t pid; char buf[BUFSIZ]; // 阻塞 sigset_t set; sigemptyset(&set); sigaddset(&set,SIGCHLD); sigprocmask(SIG_BLOCK,&set,NULL); while(1) { cfd = Accept(fd,(struct sockaddr* )&cstr_in,&cst_len); pid = fork(); if(pid == -1) perr_exit("fork error"); if(pid == 0) // 子进程 { break; } else if(pid > 0) // 父进程 { struct sigaction act; act.sa_handler = catch_child; sigemptyset(&(act.sa_mask)); act.sa_flags = 0; int r = sigaction(SIGCHLD,&act,NULL); sigprocmask(SIG_UNBLOCK,&set,NULL); // 解除阻塞 if(r != 0) perr_exit("sigaction error"); close(cfd); continue; } } if(pid == 0) { // 子进程 char ipbuf[72]; printf("客户端%s:%d 连接成功n", inet_ntop(AF_INET,&cstr_in.sin_addr.s_addr,ipbuf,sizeof(ipbuf)), ntohs(cstr_in.sin_port)); Close(fd); while (1) { int ret =Read(cfd,buf,sizeof(buf)); if(ret == 0) // 表示已经退出 { close(cfd); break; } for(int i=0;i 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)