unix底下的多线程socket程序

Squall1009 2007-04-17 07:53:41
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;
}
...全文
1406 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
linuxhaha 2007-04-23
  • 打赏
  • 举报
回复
感觉其实那些库也都是select实现的。
iambic 2007-04-23
  • 打赏
  • 举报
回复
>>asio是异步io的简称,与C不C有什么关系呢
>>现在不用,以后还是会用,不如早用。
有一个C++的库叫做asio……
flyingcp 2007-04-19
  • 打赏
  • 举报
回复
用select吧,这种东西比较好
Wolf0403 2007-04-19
  • 打赏
  • 举报
回复
Linux 上的 aio ms 只支持 ext2/3 + O_DIRECT 等很特殊的本地块设备上的情况。不知道 oyd 说的 asio 是不是另外什么东西。
oyd 2007-04-18
  • 打赏
  • 举报
回复
asio是异步io的简称,与C不C有什么关系呢
现在不用,以后还是会用,不如早用。
iambic 2007-04-18
  • 打赏
  • 举报
回复
asio什么啊,人家用的是C。
linuxhaha 2007-04-18
  • 打赏
  • 举报
回复
libgnet吧。
pacman2000 2007-04-18
  • 打赏
  • 举报
回复
一方面第一次NONBLOCK读取可能会没有读到,这时再send很可能没有发出去。因此第二次收数据时就不会收到而陷入等待。
另外,pthread不是DETACH方式而又没pthread_join的话,很可能不释放线程资源而导致线程数达到最大值或堆栈达到最大值,再也开不出线程来而失去响应。
oyd 2007-04-18
  • 打赏
  • 举报
回复
不要在线程上浪费时间了
asio吧
Squall1009 2007-04-18
  • 打赏
  • 举报
回复
换成read和write以后,
第二次int size = recv(connfd, buff, sizeof(buff), MSG_NONBLOCK);
换成read的后阻塞了, 不知道为什么不返回0,郁闷
Squall1009 2007-04-18
  • 打赏
  • 举报
回复
只是为了看 错误的,我和第一个机器之间的速度是比较快的,所以加了个MSG_NONBLOCK。
我把这个去掉看看
zhousqy 2007-04-18
  • 打赏
  • 举报
回复
if(code < 0)
printf("connect error!\n");

if(code < 0)
printf("bind error!\n");
类似这些error,程序照样往下跑的啊~
zhousqy 2007-04-18
  • 打赏
  • 举报
回复
int size = recv(connfd, buff, sizeof(buff), MSG_NONBLOCK);
int size2 = send(serfd, buff, size,MSG_NONBLOCK); //如果上面size<0呢,下面的write类同
if(size <= 0)
break;
boxban 2007-04-18
  • 打赏
  • 举报
回复

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;
}
lbaby 2007-04-18
  • 打赏
  • 举报
回复
从来不摸线程这个玩意儿,....
airlevin 2007-04-18
  • 打赏
  • 举报
回复
int * 和 void * 没什么不同么?这种情况下 free(args) 编译器能正常处理之?

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

pthread_detach(pthread_self());

看看

或者你输出一下统计,看在什么情况下服务停止,比如进行了多少次服务(创建了多少个线程)后。
Squall1009 2007-04-18
  • 打赏
  • 举报
回复
好象没有core文件生成.........

free(args);是没有问题的


jixingzhong 2007-04-18
  • 打赏
  • 举报
回复
进来瞅瞅......

恩,指派狒狒搞定 !
Squall1009 2007-04-18
  • 打赏
  • 举报
回复
........我一直没敢用root来跑这个程序
airlevin 2007-04-18
  • 打赏
  • 举报
回复
void * proxythread(void * args)
{
int i = 0;

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

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

至于两个死循环里面的 read 和 write,你给的代码很简略,所以不好说有什么问题。
加载更多回复(9)

69,371

社区成员

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

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