并发服务器的一种实现
结合多进程实现为多个客户端提供服务。
关键点:多进程,信号。
代码如下:
#include <stdio.h>
#include <t_net.h>
#include "do_trans.h"
void doit(int num){
waitpid(-1,NULL,WNOHANG);
}
int main(void){
char IP[64];
//用于和客户端连接的文件描述符
int fd_accept;
//声明一个IPV4地址家族类型的变量,这个变量是具体的通讯地址,包括IP地址和端口号
SA4 clie;
//创建一个通讯端点
int fd_socket = s_bind(AF_INET,SOCK_STREAM,6666);
if(fd_socket == -1){
perror("socket");
return -1;
}
//将socket设置为被动连接,当有连接到来的时候,将连接放入未决连接队列中
listen(fd_socket,5);
//注册一个17号信号处理函数,当子进程死亡的时候会发送17号信号给父进程
signal(17,doit);
while(1){
int len_clie = sizeof(clie);
//从未决连接队列中取出一个连接进行通讯
fd_accept = accept(fd_socket,(SA *)&clie,&len_clie);
if(fd_accept == -1){
perror("accept");
return -1;
}
//cli地址里存放的是客户端的ip地址和端口号
//当前的ip地址格式 uint32_t port uint16_t 网络字节序
printf("someone is connected,");
printf("%s",inet_ntop(AF_INET,&clie.sin_addr,IP,64));
printf(":%hu\n",ntohs(clie.sin_port));
/*并发*/
//创建子进程
pid_t pid = fork();
if(pid == -1){
perror("fork");
return -1;
}
if(pid == 0){//子进程执行的程序
//结束后关闭子进程的通讯端点的文件描述符
close(fd_socket);
//业务处理
do_trans(fd_accept);
//结束后关闭这次连接的文件描述符
close(fd_accept);
//结束后退出进程
exit(0);
}
else{//父进程执行的程序
//父进程不处理任何连接
close(fd_accept);
}
}
close(fd_socket);
return 0;
}
基于UDP的网络编程
#include <t_net.h>
#include <stdio.h>
int main(int argc,char *argv[]){
SA4 serv = {0};
char msg[1024] = {0};
char buf[1024] = {0};
//分配描述符,绑定到本地地址和端口号
int fd_socket = socket(AF_INET,SOCK_DGRAM,0);
if (fd_socket == -1){
perror("socket");
return -1;
}
serv.sin_family = AF_INET;
serv.sin_port = htons(10001);
inet_pton(AF_INET,argv[1],&serv.sin_addr);
while(1){
//fgets(msg,1024,0);
scanf("%s",msg);
int flag_send = sendto(fd_socket,msg,1024,0,(SA *)&serv,sizeof(SA4));
if(flag_send == -1){
perror("sendto");
return -1;
}
int flag_recv = recvfrom(fd_socket,buf,1024,0,NULL,0);
if(flag_recv == -1){
perror("recvfrom");
return -1;
}
write(1,buf,flag_recv);
}
close(fd_socket);
return 0;
}