#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUF_SIZE 1024
int listen_sock = 0;
int connect_sock = 0;
char message[BUF_SIZE] = {0};
socklen_t clnt_addr_sz;
pid_t pid;
struct sockaddr_in serv_addr, clnt_addr;
void handler_recycle(int signum)
{
waitpid(-1,NULL,WNOHANG);
printf("customer success to cut connect\n");
return;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
void do_connect()
{
int n = 0;
clnt_addr_sz = sizeof(serv_addr);
while(1)
{
memset(message,0,sizeof(message));
clnt_addr_sz=sizeof(clnt_addr);
n = recv(connect_sock, message, sizeof(message),0);
if (n<0)
{
perror("Fail to recv");
exit(EXIT_FAILURE);
}
else if(n == 0)
{
printf("client is not connect\n");
exit(EXIT_FAILURE);
}
printf("usepid: %d\n",getpid());
printf("recv %d bytes: %s\n",n,message);
n = send(connect_sock, message, sizeof(message),0);
if (n<0)
{
perror("Fail to send");
exit(EXIT_FAILURE);
}
else if(n == 0)
{
printf("client is not connect");
exit(EXIT_FAILURE);
}
if (strncmp(message,"quit",4) == 0)
break;
}
}
void accept_create()
{
connect_sock = accept(listen_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_sz);
if (connect_sock < 0)
{
perror("Fail to accept");
exit(EXIT_FAILURE);
}
printf("==================================\n");
printf("connect_sock: %d\n",connect_sock);
printf("client IP: %s\n",inet_ntoa(clnt_addr.sin_addr));
printf("client port: %d\n",ntohs(clnt_addr.sin_port));
}
void fork_user()
{
while(1)
{
accept_create();
pid = fork();
if (pid <0)
{
perror("Fail to fork");
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
close(listen_sock);
do_connect();
}
else if (pid > 0)
{
close(connect_sock);
}
}
}
int main(int argc, char *argv[])
{
if(argc!=3)
{
printf("Usage: %s <port>\n", argv[0]);
exit(1);
}
if (signal(SIGCHLD,handler_recycle) == SIG_ERR) //用户子进程退出信号处理
{
perror("Fail to signal\n");
exit(EXIT_FAILURE);
}
listen_sock=socket(AF_INET, SOCK_STREAM, 0); //创建一个面向消息类型的套接字
if(listen_sock==-1)
error_handling("TCP socket creation error");
memset(&serv_addr, 0, sizeof(serv_addr)); //填充IP及端口信息
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
serv_addr.sin_port=htons(atoi(argv[2]));
clnt_addr_sz = sizeof(clnt_addr);
if (bind(listen_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1) //将通信地址信息绑定到套接字上,构成UDP套接字
error_handling("bind() error");//绑定IP到服务器
if ( listen(listen_sock,5) == -1)
{
perror("Fail to listen");
exit(EXIT_FAILURE);
}
printf("Listen...\n");
fork_user();
return 0;
}