您的位置:首页 > 理论基础 > 计算机网络

unix/linux socket 编程一,简单多进程tcp socket server流程

2010-06-10 17:14 726 查看
多进程socket server工作流程

1。创建socket句柄。

2。设置监听地址及端口号。

3。绑定到socket句柄上。

4。监听。

5。等待客户端连接。

6。创建子进程,处理客户端请求。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#define SERV_PORT 9999
#define LISTENQ 10

typedef struct sockaddr SA;
typedef void Sigfunc(int);

//void (* signal(int signo, void(*func)(int)))(int);
//封装信号处理函数
Sigfunc * signal(int signo, Sigfunc *func)
{
struct sigaction act, oact;

act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(sigaction(signo, &act, &oact) < 0)
return (SIG_ERR);
return(oact.sa_handler);
}

//处理子进程退出,子进程退出会向主进程发送SIG_CHILD信号
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d terminated/n", pid);
return;
}

int main(int argc, char **argv)
{
int fd;
int readlen = 0;
char sMsg[11];
int listen_fd, connect_fd, clilen, childpid;
struct sockaddr_in servaddr, cliaddr;

printf("test sock srv/n");

if((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket error/n");
return -1;
}

memset(&servaddr, 0x00, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);

if(bind(listen_fd, (SA *)&servaddr, sizeof(servaddr)) < 0)
{
printf("bind error/n");
return -2;
}

if(listen(listen_fd, LISTENQ) < 0)
{
printf("listen error/n");
return -3;
}

signal(SIGCHLD, sig_chld);
for(;;)
{
clilen = sizeof(cliaddr);
memset(&cliaddr, 0x00, sizeof(cliaddr));
if((connect_fd = accept(listen_fd, (SA *)&cliaddr, &clilen)) < 0)
{
//如果accept被信号中断,则重启
if(errno == EINTR || errno == ECONNABORTED)
continue;
else
{
printf("accept error/n");
return -4;
}
}
if((childpid = fork()) == 0)
{
close(listen_fd);
for(;;)
{
memset(sMsg, 0x00, sizeof(sMsg));
if( (readlen = read(connect_fd, sMsg, 10)) < 0)
{
close(connect_fd);
printf("readn error/n");
return -5;
}
write(fd, sMsg, readlen);
}
close(connect_fd);
return 0;
}
close(connect_fd);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: