UNIX下多进程的服务器程序开发请教!高分相送!!!

sjmblue 2004-02-02 10:44:21
想编写一个UNIX下的多进程的服务器端程序,作为一个服务器后台运行,接受客户端的发来的数据包,是通过socket进行数据交互的!

原来的是个单进程的,现在想写成一个后台多进程的程序,并且能较好的处理僵尸进程,但感到无从下手,虽然知道如何fork,如何exec,想请教哪位能给个较好的例子或是相关资料或是相关经验,多谢多谢!!!
...全文
31 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sjmblue 2004-02-03
  • 打赏
  • 举报
回复
多谢诸位,尤其是sunriselx() ,先好好研究 一下再来讨教!!!
xinyi 2004-02-03
  • 打赏
  • 举报
回复
多線程不好,程序一出錯,守護進程就沒了,還是多進程好
icesg 2004-02-02
  • 打赏
  • 举报
回复
you can use posix
yuanlei1978113 2004-02-02
  • 打赏
  • 举报
回复
我想你是用多线程配合select不是更好吗!注意在客户端断开连接后服务器最好关闭
与之连接socket。
passingguy 2004-02-02
  • 打赏
  • 举报
回复
要避免zombie,用sigaction函数
sunriselx 2004-02-02
  • 打赏
  • 举报
回复
手头刚好有个简单的例子,不太好,但基本能说明问题,里面没有做daemon的初始化,这种方式客户端不能太多,几百个就差不多了。

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>

#include <iostream>
#include <list>
#include <algorithm>
using std::list;
using std::cerr;
using std::endl;

int start_listen(unsigned long port)
{
int ls = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);

if (bind(ls, (struct sockaddr *)&addr, sizeof(struct sockaddr)) != 0) {
close(ls);
return -1;
}

if (listen(ls, 2000) != 0) {
close(ls);
return -1;
}

return ls;
}

int get_client(int ls)
{
int ret = -1;

fd_set rSet;
FD_ZERO(&rSet);
FD_SET(ls, &rSet);

timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (select(ls + 1, &rSet, 0, 0, &timeout) > 0
&& FD_ISSET(ls, &rSet)) {
sockaddr_in addr;
socklen_t len = sizeof(sockaddr);
errno = 0;
int cs = accept(ls, (sockaddr*)&addr, &len);
if (cs > 0) {
ret = cs;
} else {
perror("accept failed");
}
}

return ret;
}

void serve_client(int cs)
{
char buf[1024];
while (1) {
sleep(1);

// recv something from client
memset(buf, 0, sizeof(buf));
int len = recv(cs, buf, sizeof(buf), 0);
if (len < 0) {
cerr << "recv error" << endl;
break;
} else if (len == 0) {
cerr << "client close connection" << endl;
close(cs);
break;
}
// send data back
if (send(cs, buf, len, 0) != len) {
cerr << "send data back error" << endl;
break;
}
}
}

int main(int, char**)
{
int ls = start_listen(20000);
if (ls < 0) {
cerr << "listen failed" << endl;
return -1;
}

list<long> childs(0);
while (1) {
int cs = get_client(ls);
if (cs > 0) {
cerr << "got client : " << cs << endl;
pid_t pid= fork();
if (pid < 0) {
cerr << "fork failed" << endl;
return -1;
} else if (pid == 0) {
serve_client(cs);
return 0;
}
close(cs);
childs.push_back(pid);
cerr << "client_num : " << childs.size() << endl;
}
pid_t child;
while ((child = waitpid(-1, 0, WNOHANG)) > 0) {
list<long>::iterator cit = find(childs.begin(), childs.end(), child);
if (cit != childs.end()) {
childs.erase(cit);
cerr << "client_num : " << childs.size() << endl;
}
}
}

return 0;
}
rexp 2004-02-02
  • 打赏
  • 举报
回复
你一定要用fork也是可以的,
exec是不需要了。
SIGCHLD处理一把
icedust 2004-02-02
  • 打赏
  • 举报
回复
use libpthread

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧