回射服务器没有做出错处理:
回射服务器 C语言代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <signal>
#define SERV_PORT 5000
#define MAXLINE 64
void str_echo(int fd);
void sig_chld(int signo);
int main(int argc, char **argv)
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd, 5);
// 获取子进程的结束信号并用sig_chld做处理, signal()函数在多线程显示是没有定义的
// 一般是用sigaction来替换, 我这图方便
if (signal(SIGCHLD, sig_chld) == SIG_ERR){
fprintf(stderr, "can't catch SIGCHLD \n");
exit(0);
}
for ( ; ; ){
clilen = sizeof(cliaddr);
if ( (connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0){
if (errno == EINTR) // accept 在阻塞的时候被signal打断会返回EINTR错误存于errno
continue; // back to for()
else{
fprintf(stderr, "accept error\n");
exit(0);
}
}
if ((childpid = fork()) == 0){ // child
close(listenfd); // close listening socket
str_echo(connfd);// process the request
exit(0);
}
close(connfd); // parent closes connected socket
}
return 0;
}
void str_echo(int sockfd)
{
int n;
char buf[MAXLINE];
again:
while ( (n = read(sockfd, buf, MAXLINE)))
write(sockfd, buf, n);
if (n < 0 && errno == EINTR)
goto again;
else if (n < 0)
printf("str_echo: read error");
}
void sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated\n", pid);// printf() isn't suitable for use here
return;
}
回射服务单线程select版本
#include <sys/types.h>
#include <netinet/in.h>
#in