Files
C-exp-collection/server-exp2/togglesp.c

84 lines
2.5 KiB
C
Raw Normal View History

2026-05-28 08:48:01 +08:00
#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);
}
2026-06-09 06:43:13 +02:00
//工作函数
2026-05-28 08:48:01 +08:00
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++) {
2026-06-09 06:43:13 +02:00
conn_sock = accept(listen_sock, (SA *) &clientaddr, &clientlen);
2026-05-28 08:48:01 +08:00
2026-06-09 06:43:13 +02:00
/* 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);
2026-05-28 08:48:01 +08:00
2026-06-09 06:43:13 +02:00
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!) */
2026-05-28 08:48:01 +08:00
}
}