服务器大致流程图
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <ctype.h>
#include <strings.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 6666
void catch_child(int signo)
{
while( waitpid(0, NULL, WNOCHANG) > 0 );
return ;
}
int main(int argc, char *argv[])
{
int lfd cfd;
pid_t pid;
char buf[BUFSIZ];
int ret, i;
struct sockaddr_in srv_addr, clt_addr; //创建客户端与服务器地址
socklen_t clt_addr_len; //定义客户端地址长度
srv_addr.sin_family = AF_INET; //初始化服务器地址
srv_addr.sin_port = htons(SERV_PORT);
srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
lfd = socket(AF_INET, SOCK_STREAM, 0); //创建socket
bind(lfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
listen(lfd, 128);
clt_addr_len = sizeof(clt_addr)
while(1)
{
cfd = accept(lfd, (struct sockaddr *)&clt_addr, clt_addr_len);
pid = fork();
if(pid < 0)
{
perror("fork error\n");
exit(1);
}else if(pid == 0){ //子进程
close(lfd);
break;
}else{
//回收子进程
struct sigaction act;
act.sa_handler = catch_child;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGCHLD, &act, NULL); //注册信号捕捉
if(ret != 0)
{
perror("sigaction error\n");
exit(1);
}
close(cfd); //关闭与客服端通信套接字
continue;
}
}
//子进程 处理
if(pid == 0)
{
for(;;) //死循环
{
//读 客服端数据
ret = read(cfd, buf, sizeof(buf));
if(ret == 0) //客服端 关闭
{
close(cfd);
exit(1);
}
//小 -> 大
for(i = 0; i < ret; i++)
{
buf[i] = toupper(buf[i]);
}
write(cfd, buf, ret); //发回去
write(STDOUT_FILENO, buf, ret); //显示到屏幕中
}
}
return 0;
}