#include <sys/socket.h> #include <unistd.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <strings.h> #include <syslog.h> #include <signal.h> #include <fcntl.h> #define PORT 4000 #define MAXFD 64 void daemon_init(const char *pname, int facility) { int i; pid_t pid; if((pid=fork())!=0) _exit(0);//父进程结束,shell回到命令提示符状态; //子进程属于父进程的进程组,从而保证了子进程不是所属组的组长进程,为下面调用函数setsid做好准备; setsid();//产生一个新的会话组并使自己成为会话组的组长; signal(SIGHUP,SIG_IGN);//忽略与控制台相关的信号,这样当控制台被关闭或者会话组长终止时系统发来的HUP信号被忽略,从而继续运行; if((pid=fork())!=0)//再次产生自进程,父终止,子进程从而不再是会话组长,因此它再也不会获得控制终端。根据SVR4规定:当没有控制终端的会话组长打开终端设备时,该终端自动成为这个会话组长的控制终端。 _exit(0); chdir("/"); umask(0);//清除创建文件的掩码; for(i=0;i<MAXFD;i++) close(i); i=open("/dev/null",O_RDWR,0); if(i!=-1) { dup2(i,STDIN_FILENO); dup2(i,STDOUT_FILENO); dup2(i,STDERR_FILENO); close(i); } openlog(pname,LOG_PID,facility); } main(int argc,char *argv[]) { pid_t pid; int listen_socket_id,accept_socket_id; int addrlen, iBytes; unsigned char buf[256]; struct sockaddr_in server, client; if(argc < 3){ printf("Too less parameters/n"); printf("Usage: ./tcp_server ip port/n"); _exit(0); } daemon_init(argv[0],0); if((listen_socket_id = socket(AF_INET, SOCK_STREAM, 0))== -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error--socket"); _exit(-1); } bzero(&server, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(atoi(argv[2])); if(strcmp(argv[1],"0")==0) server.sin_addr.s_addr = htonl(INADDR_ANY); else server.sin_addr.s_addr = inet_addr(argv[1]); int opt = SO_REUSEADDR; setsockopt(listen_socket_id,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if(bind(listen_socket_id,(struct sockaddr *)&server, sizeof(server)) == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-bind:"); close(listen_socket_id); _exit(-2); } if(listen(listen_socket_id, 5) == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-listen:"); close(listen_socket_id); _exit(-3); } addrlen = sizeof(addrlen); for(;;){ if((accept_socket_id = accept(listen_socket_id, (struct sockaddr *)&client, &addrlen)) == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-accept:"); close(listen_socket_id); _exit(-4); } pid = fork(); if(pid > 0) { //父进程 close(accept_socket_id); continue; } else if(pid == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-fork:"); close(accept_socket_id); close(listen_socket_id); _exit(-5); } //子进程 close(listen_socket_id); bzero(buf,256); iBytes = read(accept_socket_id, buf, 256); if(iBytes == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-recv:"); close(accept_socket_id); _exit(-6); } printf("[%s:%d]发来连接请求:%s/n",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf); if(write(accept_socket_id,"Welcome, baby!/n",15) == -1){ syslog(LOG_INFO|LOG_LOCAL0,"Error-send:"); close(accept_socket_id); _exit(-7); } close(accept_socket_id); _exit(0); } }