/* ============================================================================ Name : TCPserver.c Author : vestinfo Version : 1.1 Copyright : www.cnblogs.com/vestinfo Description : TCP server ============================================================================ */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8888 #define MAXLENGTH 256 int main() { int listenfd,connfd; struct sockaddr_in servaddr; struct sockaddr_in clientaddr; char msgbuffer[MAXLENGTH]; socklen_t len; /* 创建监听套接字 */ if((listenfd = socket(AF_INET, SOCK_STREAM,0)) < 0) { perror("socket"); exit(1); } /* 绑定server的端口 */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("bind"); } /* 开始监听 */ if(listen(listenfd, 5) < 0) { perror("listen"); exit(1); } else { printf("socket create、bind successfully!\nlistening......\n"); } for( ; ; ) { /* 接收来自client的连接请求 */ len = sizeof(clientaddr); if((connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &len)) < 0) { perror("accept"); continue; } if( fork() == 0 ) //子进程 { printf("the connect is from:%s\n",inet_ntoa(clientaddr.sin_addr)); close(listenfd); //子进程关闭监听套接字。 for( ; ; ) { bzero(msgbuffer, MAXLENGTH); if(read(connfd, msgbuffer, MAXLENGTH) <= 0) { perror("read from client"); break; } else { printf("read from client:%s", msgbuffer); } if( write(connfd, msgbuffer, strlen(msgbuffer)) < 0) { perror("write to client"); break; } } close(connfd); //该句可省略,这里为了强调关闭描述符这个操作。 exit(0); } else { //可以去掉else,直接写close(connfd);此处else为了区分父子进程的执行内容。 close(connfd); //父进程关闭accept返回的新的连接描述符。 } } return 0; }