linux c 多进程socket程序,如何实现父进程监听,子进程接受连接(注有多个子进程)

wwm86 2011-11-06 11:07:52
主要代码如下:


main()
{
/*建立socket,设置地址可以重用,绑定端口,监听*/
 ...(代码省略)
pid_t pid;
if((pid=fork()) > 0) /*主进程执行部分*/
{
/*执行一些进程管理任务,代码省略*/
...
}
else if (pid == 0)/*子进程执行部分*/
{
/*为表示简单,出错处理就不写出来了*/
int fd=accept(listenFd,(sturct sockaddr*)&clientAddr,&addrLen);
/*下在就是接收数据,对数据进行处理*/
...
}
}



现在问题是用一个程序来测试的时候,总是一有连接到来,就有一个子进程挂掉了,测试程序连接不上。
求高手解答,感激不尽!!!
...全文
579 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
wwm86 2011-11-07
  • 打赏
  • 举报
回复
呵呵,谢谢5楼,下午再试试。成功就给分,谢谢你的意见。
youkuxiaobin 2011-11-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

这是apache的Prefork模式,预先创建N个子进程,父进程只负责子进程管理。

每一个子进程mutex_lock(); accept(); mutex_unlock();

楼主的问题就是没加锁accept,问题就是一个客户端connect将唤醒所有的子进程accept,这叫惊群现象。

而楼主悲哀的就是编码习惯不好,从来不会检查函数的返回值,自以为accept返回就是有连接到……
[/Quote]
惊叹5楼的实力!!!
天云 2011-11-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 qq120848369 的回复:]

这是apache的Prefork模式,预先创建N个子进程,父进程只负责子进程管理。

每一个子进程mutex_lock(); accept(); mutex_unlock();

楼主的问题就是没加锁accept,问题就是一个客户端connect将唤醒所有的子进程accept,这叫惊群现象。

而楼主悲哀的就是编码习惯不好,从来不会检查函数的返回值,自以为accept返回就是有连接到……
[/Quote]

++
qq120848369 2011-11-07
  • 打赏
  • 举报
回复
这是apache的Prefork模式,预先创建N个子进程,父进程只负责子进程管理。

每一个子进程mutex_lock(); accept(); mutex_unlock();

楼主的问题就是没加锁accept,问题就是一个客户端connect将唤醒所有的子进程accept,这叫惊群现象。

而楼主悲哀的就是编码习惯不好,从来不会检查函数的返回值,自以为accept返回就是有连接到来,于是程序跑成什么样都有可能了,一般是段错误退出。
liufang421 2011-11-07
  • 打赏
  • 举报
回复
socket 能跨进程?
wwm86 2011-11-07
  • 打赏
  • 举报
回复
问题找出来了,原来最不容易出问题的地方出了问题,一个printf导致子进程挂掉了。解决了,谢谢了。
wwm86 2011-11-06
  • 打赏
  • 举报
回复
我问题描述得不清楚,我说清楚点。
[code=c/c++]

int workPro(int fd)
{
/*接受连接,收发数据*/
fd=accept(listenFd,(sturct sockaddr*)&clientAddr,&addrLen);
...
}

int MakeChild(int fd)
{
pid_t pid;
if((pid=fork())>0)
{
return 0;
}
else if(pid ==0)
{
workpro(fd);
}
}

main()
{
/*建立socket,设置地址可以重用,绑定端口,监听*/
 ...(代码省略)
pid_t pid;
int i;
for(i=0;i!= MAXPROCESS;i++)
{
MakeChild(listenFd);
}
}
[/code]

这样的父进程监听,多子进程接爱连接,当有连接来到时候就会有一个子进程挂掉,问题出在哪?请高手赐教。
「已注销」 2011-11-06
  • 打赏
  • 举报
回复

#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <stdbool.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "c_timer.h"
#define bufSize 512
//#define printFileReceivedFromServer false
#define printFileReceivedFromServer true
#define debug 0

typedef struct clientDS
{
char *host;
int port;
char *filename;
int index;
}clientDS;

//int client (char *host, int port, char *filename);
void *client (void *s);
void runClient();

int main (int argc, char *argv[])
{
char *host, *filename;
int port, r;

//assert (argc == 4);
if(argc!=6)
{
fprintf(stderr, "Please follow the format: ./client ip port1101 filename clientNumber runtime.\n");
exit(1);
}
host = argv[1];
port = atoi (argv[2]);
filename = argv[3];
int clientNumber = atoi(argv[4]);
int runTime = atoi(argv[5]);

double total = 0;
int i = 0;
for(i=0; i<runTime; i++)
{
double start = get_cur_time();
runClient(host, port, filename, clientNumber);
double end = get_cur_time();
printf("Run time %d: %lf.\n", i, end-start);
total = end-start;
}
printf("Total Time: %lf, average: %lf.\n", total, total/runTime);
return 1;
}

void runClient(char *host, int port, char *filename, int clientNumber)
{
int i = 0;
pthread_t thread_ID[clientNumber];
for(i=0; i<clientNumber; i++)
{
// client (host, port, filename);
clientDS *cds = (clientDS *)malloc(sizeof(clientDS));
cds->host = host;
cds->port = port;
cds->filename = filename;
cds->index = i;
pthread_create(&thread_ID[i], NULL, client, (void *)(cds));
//free(cds);
}

void *exitstatus;
for(i=0; i<clientNumber; i++)
{
pthread_join(thread_ID[i], &exitstatus) ;
}
}

//int client (char *host, int port, char *filename)
void *client (void *c)
{
clientDS cds = *((clientDS *)c);

char *host = cds.host;
int port = cds.port;
char *filename = cds.filename;
int index = cds.index;

int r, s;
struct sockaddr_in sin;
char buf[bufSize];

/* Setup the socket */
s = socket (AF_INET, SOCK_STREAM, 0);
if( s==-1)
{
perror("socket");
fprintf(stderr, "socket error\n.");
exit(1);
}

/* Make the connection */
bzero (&sin, sizeof (sin));
sin.sin_family = AF_INET;
sin.sin_port = htons (port);
inet_aton (host, &sin.sin_addr);

int cval =connect (s, (struct sockaddr *) &sin, sizeof (sin));
if(cval == -1)
{
perror("connect");
exit(1);
}

/* Write the filename */
write (s, filename, strlen (filename));
write (s, "\n", 1);

if(debug) fprintf(stdout, "%d begin to read: %s.\n", cds.index, cds.filename);

/* Send the bytes that come back to stdout */
while ((r = read (s, buf, sizeof (buf))) > 0)
{
write (1, buf, r);
if(printFileReceivedFromServer || debug)
fprintf(stdout, "client %d: %d bytes are written.\n", cds.index, r);
}

/* Finish out */
close (s);
if(debug) fprintf(stdout, "Client %d Finish copying.\n", index);
return 0;
}
「已注销」 2011-11-06
  • 打赏
  • 举报
回复
accept 外面用个while吧


#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define bufSize 512
#define debug 1

/* s1 is a TCP socket from a client */
void handle(int s1)
{
if(!debug) printf("%d.\n", s1);
char request[bufSize], buf[bufSize];
int i = 0, n, fd;
char c;

/* Read the request (a file name) from the client. */
while(read(s1, &c, 1) == 1 && c != '\n' && c != '\r'
&& i < sizeof(request)-1)
{
request[i++] = c;
if(!debug) printf("%c", c);
}
request[i] = '\0';

/* Open the file, send the contents to the client. */
printf("Filename: %s\n", request);
fd = open(request, 0);
if(fd!=-1)
{
while((n = read(fd, buf, sizeof(buf))) > 0)
write(s1, buf, n);
close(fd);
}
else
fprintf(stderr, "open: No such file or directory.\n");
close(s1);
}

int setup(int port)
{
int s; //socket file descriptor
struct sockaddr_in sin;

/* Allocate a TCP/IP socket. */
// s = socket(AF_INET, SOCK_STREAM, 0);
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s==-1)
{
perror("socket");
fprintf(stderr, "socket error\n.");
exit(1);
}

/* Listen for connections on port (http). */
bzero(&sin, sizeof(sin));
// bzero(&sin, sizeof(struct sockaddr_un));
sin.sin_family = AF_INET;
// sin.sin_family = AF_UNIX;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
if( -1 == bind(s, (struct sockaddr *)&sin, sizeof(sin)) )
{
perror("bind");
exit(1);
}
// bind(s, (struct sockaddr *)&sin, sizeof(struct sockaddr_un));
fprintf(stdout, "start listening.\n");
listen(s, 8);

return(s);
}

void server_1(int port)
{
int s, s1, addrlen;
//struct sockaddr_in from;
struct sockaddr from;

/* create a TCP socket that listens for HTTP connections */
s = setup(port);

while(1) {
/* Wait for a new connection from a client. */
addrlen = sizeof(from);
s1 = accept(s, &from, &addrlen);
if(!debug) printf("%d.\n", s1);
if(s1 == -1)
{
perror("accept");
exit(1);
}
/* Perform the client's request. */
handle(s1);
}

}

void server_2(int port)
{
int s = setup(port);
int i;
for(i=0; i<1; i)
{
struct sockaddr from;
int addrlen = sizeof(from);
int s1 = accept(s, &from, &addrlen);
/* Create a new child process. */
if(fork() == 0) {
/* Perform the client’s request in the child process. */
handle(s1);
exit(0);
}
close(s1);

/* Collect dead children, but don’t wait for them. */
int status;
waitpid(-1, &status, WNOHANG);
}
}

int main(int argc, char *argv[])
{
if(argc!=2)
{
fprintf(stderr, "Please follow the format: ./proc_server port(1101).\n");
exit(1);
}
server_1(atoi(argv[1]));
return 1;
}

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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