Files
2026-06-09 06:43:13 +02:00

84 lines
2.5 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "common.h"
void sigchld_handler(int sig)
{
while (waitpid(-1, 0, WNOHANG) > 0);
return;
}
typedef void (*sighandler_t) (int sig) ;
void Signal(int sig, sighandler_t handler){
struct sigaction sa;
sa.sa_handler = sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; // 确保被信号中断的系统调用自动重启
sigaction(SIGCHLD, &sa, NULL);
}
//工作函数
void toggle(int conn_sock,int hit)
{
size_t n; int i,no=0;
char buf[MAXLINE];
printf("第%d个客户通信开始\n",hit);
while((n =recv(conn_sock, buf, MAXLINE,0))> 0) {
printf("toggle服务器收到第%d个客户第%d个消息,长度为%d字节\n", hit,++no,(int)n);
for(i=0; i<n; i++)
if(isupper(buf[i]))
buf[i]=tolower(buf[i]);
else if(islower(buf[i]))
buf[i]=toupper(buf[i]);
send (conn_sock, buf, n, 0);
}
printf("第%d个客户通信结束\n",hit);
}
int main(int argc, char **argv)
{
int listen_sock, conn_sock, port;
struct sockaddr_in clientaddr;
struct hostent *hp;
char *haddrp;
int hit;
socklen_t clientlen=sizeof(struct sockaddr_in);
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(1);
}
port = atoi(argv[1]);
//设置SIGHLD的信号处理函数用于收割结束的子进程
Signal(SIGCHLD, sigchld_handler);
listen_sock = open_listen_sock(port);
if( listen_sock==-1) {
printf("端口号%d繁忙\n",port);
exit(1);
}
for(hit=1; ; hit++) {
conn_sock = accept(listen_sock, (SA *) &clientaddr, &clientlen);
/* determine the domain name and IP address of the client */
hp = gethostbyaddr((const char *)&clientaddr.sin_addr.s_addr,
sizeof(clientaddr.sin_addr.s_addr), AF_INET);
haddrp = inet_ntoa(clientaddr.sin_addr);
printf("server connected to %s (%s)\n", hp->h_name, haddrp);
if (fork() == 0) {
close(listen_sock); /* Child process closes its listening socket */
toggle(conn_sock,hit); /* Child process services client */
close(conn_sock); /* Child process closes connection with client */
exit(0); /* Child process exits */
}
close(conn_sock); /* Parent closes connected socket (important!) */
}
}