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……