首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

unix底下的多线程socket程序解决思路

2012-04-11 
unix底下的多线程socket程序unix底下的多线程socket程序,其想实现的内容是把收到的内容发送到指定的Server

unix底下的多线程socket程序
unix底下的多线程socket程序,其想实现的内容是把收到的内容发送到指定的Server,并且把Server返回的内容返回到客户端,就像一个中转站一样,想用来做http的代理服务器的,但是现在程序老是down掉。大家看看有什么问题,向用多线程实现的。


#include   <sys/types.h>
#include   <sys/socket.h>
#include   <netinet/in.h>
#include   <arpa/inet.h>
#include   <netdb.h>
#include   <unistd.h>
#include   <fcntl.h>
#include   <strings.h>
#include   <stdio.h>
#include   <errno.h>
#include   <pthread.h>
#include   <stdlib.h>

void   *   proxythread(void   *   args);

int   main()
{
int   listenfd;
int   code;
struct   sockaddr_in   servaddr;
listenfd   =   socket(AF_INET,   SOCK_STREAM,   0);
if(listenfd   <   0)
printf( "main   error!\n ");
bzero(&servaddr,   sizeof(servaddr));
servaddr.sin_family   =   AF_INET;
servaddr.sin_addr.s_addr   =   htonl(INADDR_ANY);
servaddr.sin_port   =   htons(8234);
code   =   bind(listenfd,   (struct   sockaddr   *)   &servaddr,   sizeof(servaddr));
if(code   <   0)
printf( "bind   error!\n ");
listen(listenfd,   128);
for(;;)
{
pthread_t   tid;
int   *   connfd   =   (int   *)malloc(sizeof(int));  
*connfd   =   accept(listenfd,   (struct   sockaddr   *)   NULL,   NULL);
pthread_create(&tid,   NULL,   proxythread,   connfd);
}
return   0;
}


void   *   proxythread(void   *   args)
{
int   i   =   0;

int   connfd   =   *((int   *)args);
free(args);
if(connfd   <   0)
printf( "accpet   error!\n ");

struct   sockaddr_in   proxyser;
int   serfd   =   socket(AF_INET,   SOCK_STREAM,   0);
if(serfd <   0)
printf( "socekt   error   in   child!\n ");
bzero(&proxyser,   sizeof(proxyser));
proxyser.sin_family   =   AF_INET;
proxyser.sin_port   =   htons(8081);
inet_pton(AF_INET,   "22.11.98.229 ",   &proxyser.sin_addr);
int   code   =   connect(serfd,   (struct   sockaddr   *)   &proxyser,   sizeof(proxyser));
if(code   <   0)
printf( "connect   error!\n ");
for(;;)
{
char   buff[8192];
memset(buff,   0,   8192);
int   size   =   recv(connfd,   buff,   sizeof(buff),   MSG_NONBLOCK);
int   size2   =   send(serfd,   buff,   size,MSG_NONBLOCK);
if(size   <=   0)
break;
}
for(;;)
{
char   buff[8192];
memset(buff,   0,   8192);
int   size   =   read(serfd,   buff,   sizeof(buff));
int   size2   =   write(connfd,   buff,   size);
if(size   <=   0)
break;
}
close(serfd);
close(connfd);
return   NULL;
}


[解决办法]
何时是个尽头,不如用asio网络库,已经通过boost库,也许就是将来的标准库
------解决方案--------------------


晕倒,
if(size <= 0)
break;

而且你用这段代码还是太简单了,还是要select
[解决办法]
好久不见楼主
第一次见这种 1 thread per client 模型的代码
[解决办法]
可能是发送的数据对方来不及处理,造成网络缓冲已满时调用了reset().
[解决办法]
申请的动态存储空间也要释放.
[解决办法]
运行时候打开 ulimit -c unlimited 然后分析 core file 吧。。。
[解决办法]
你两个死循环里面滴
if(size <= 0)
break;
跳出条件有问题吧 还有你申请滴空间释放也有问题
[解决办法]
void * proxythread(void * args)
{
int i = 0;

int connfd = *((int *)args);
free(args);

args 是 (void *),这里的 free 会有问题。你的程序死掉可能就是因为这个问题。

至于两个死循环里面的 read 和 write,你给的代码很简略,所以不好说有什么问题。
[解决办法]
进来瞅瞅......

恩,指派狒狒搞定 !
[解决办法]
int * 和 void * 没什么不同么?这种情况下 free(args) 编译器能正常处理之?

如果不是内存和收发方面的内存溢出之类的情况,那么可能是线程设置上的问题?
线程开始后加上:

pthread_detach(pthread_self());

看看

或者你输出一下统计,看在什么情况下服务停止,比如进行了多少次服务(创建了多少个线程)后。
[解决办法]
从来不摸线程这个玩意儿,....

[解决办法]

for(;;)
{
char buff[8192];
memset(buff, 0, 8192);
int size = recv(connfd, buff, sizeof(buff), MSG_NONBLOCK);
//你设置了 NONBLOCK,如果此时没有数据,recv很可能返回-1
//接下来再用size作参数调用send,可能会有麻烦
int size2 = send(serfd, buff, size,MSG_NONBLOCK);
if(size <= 0)
break;
}
for(;;)
{
char buff[8192];
memset(buff, 0, 8192);

//如果前面未曾将connfd上的数据转发到 serfd,
//那么下面的 read 调用将被无限期挂起

int size = read(serfd, buff, sizeof(buff));

int size2 = write(connfd, buff, size);
if(size <= 0)
break;
}

[解决办法]
int size = recv(connfd, buff, sizeof(buff), MSG_NONBLOCK);
int size2 = send(serfd, buff, size,MSG_NONBLOCK); //如果上面size <0呢,下面的write类同
if(size <= 0)
break;

[解决办法]
if(code < 0)
printf( "connect error!\n ");

if(code < 0)
printf( "bind error!\n ");
类似这些error,程序照样往下跑的啊~

[解决办法]
不要在线程上浪费时间了
asio吧
[解决办法]
libgnet吧。
[解决办法]
asio什么啊,人家用的是C。
[解决办法]
asio是异步io的简称,与C不C有什么关系呢
现在不用,以后还是会用,不如早用。
[解决办法]
一方面第一次NONBLOCK读取可能会没有读到,这时再send很可能没有发出去。因此第二次收数据时就不会收到而陷入等待。
另外,pthread不是DETACH方式而又没pthread_join的话,很可能不释放线程资源而导致线程数达到最大值或堆栈达到最大值,再也开不出线程来而失去响应。
------解决方案--------------------


Linux 上的 aio ms 只支持 ext2/3 + O_DIRECT 等很特殊的本地块设备上的情况。不知道 oyd 说的 asio 是不是另外什么东西。
[解决办法]
用select吧,这种东西比较好
[解决办法]
感觉其实那些库也都是select实现的。
[解决办法]
> > asio是异步io的简称,与C不C有什么关系呢
> > 现在不用,以后还是会用,不如早用。
有一个C++的库叫做asio……

热点排行