/*
============================================================================
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;
}