多线程非阻塞socket(select)

wuliangyue7 2008-11-10 09:21:08
#include "chat.h"
#define STDIN 0
#define STDOUT 1
#define PORT 10000
#define BACKLOG 5
#define MAXFDS 2
#define MAXMSG 100
main()
{
char msg[MAXMSG],recvmsg[MAXMSG];
fd_set rfds;
/*fd_set wfds;*/
struct timeval tv;
int srvfd,clntfd;
int recvlen;
struct sockaddr_in myserver;
struct sockaddr_in myclient;
tv.tv_sec=10;
tv.tv_usec=1000000;
if((srvfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
myserver.sin_family=AF_INET;
myserver.sin_port=htons(PORT);
myserver.sin_addr.s_addr=htonl(INADDR_ANY);
bzero(&(myserver.sin_zero),8);
if(bind(srvfd,(struct sockaddr *)&myserver,sizeof(struct sockaddr))==-1)
{
perror("bind");
exit(1);
}
printf("server listening port: %d",PORT);
if(listen(srvfd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}

while(1)
{
int size=sizeof(struct sockaddr_in);
if((clntfd=accept(srvfd,(struct sockaddr *)&myclient,&size))==-1)
{
perror("accept");
}
printf("get connection from %s\n",inet_ntoa(myclient.sin_addr));
FD_ZERO(&rfds);
FD_SET(STDIN,&rfds);
FD_SET(clntfd,&rfds);
select(MAXFDS+1,&rfds,NULL,NULL,&tv);
printf("select\n");
if(FD_ISSET(STDIN,&rfds))
{
scanf("%s",msg);
if(send(clntfd,msg,strlen(msg)+1,0)==-1)
{
perror("send");
}
printf("send");
}
else if(FD_ISSET(clntfd,&rfds))
{
if((recvlen=recv(clntfd,recvmsg,MAXMSG,0))==-1)
{
perror("recv");
}
recvmsg[recvlen]="\0";
printf("client:%s\n",recvmsg);
}
else
{
printf("time out\n");
}

}
}

1、为什么server listening port 在有client连接后才打印出来
2、没有实现非阻塞
...全文
902 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
wyswyg63 2008-11-12
  • 打赏
  • 举报
回复

select(MAXFDS+1,&rfds,NULL,NULL,&tv);
这里有问题吧,应该是
select(clntfd+1,&rfds,NULL,NULL,&tv);
Arthur_ 2008-11-12
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wuliangyue7 的回复:]
10楼的貌似有些道理
13楼的就??
[/Quote]

select对于当前进程(线程)来说是阻塞的。
wuliangyue7 2008-11-12
  • 打赏
  • 举报
回复
10楼的貌似有些道理
13楼的就??
DemonWhisper 2008-11-11
  • 打赏
  • 举报
回复
select 是典型的单线程阻塞模型用的东西……
xiaopoy 2008-11-11
  • 打赏
  • 举报
回复
学习。
帮顶
pingzi_1119 2008-11-11
  • 打赏
  • 举报
回复
up
xiezhenghai 2008-11-11
  • 打赏
  • 举报
回复
问题二、你的select函数用的有问题
accept 会引起阻塞、 recv \ send 也都会引起阻塞,要用对地方
实症下药,看哪个函数需要非阻塞的运行就得在哪个函数之前使用select 模型
wuliangyue7 2008-11-11
  • 打赏
  • 举报
回复
问题1搞定是行缓存的问题 thx
第二个问题就没人能看看吗
wuliangyue7 2008-11-11
  • 打赏
  • 举报
回复
问题1搞定是行缓存的问题 thx
第二个问题就没人能看看吗
hjzwl1018 2008-11-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 Arthur_ 的回复:]
>1、为什么server listening port 在有client连接后才打印出来
逻辑上不可能。应该是你缓冲区问题:你加个换行符试下: printf("server listening port: %d\n",PORT);


>2、没有实现非阻塞
google
[/Quote]
up...
Arthur_ 2008-11-10
  • 打赏
  • 举报
回复
>1、为什么server listening port 在有client连接后才打印出来
逻辑上不可能。应该是你缓冲区问题:你加个换行符试下: printf("server listening port: %d\n",PORT);


>2、没有实现非阻塞
google
星羽 2008-11-10
  • 打赏
  • 举报
回复
星羽 2008-11-10
  • 打赏
  • 举报
回复
用vs2005编译 运行了一下

server listening port: 10000


这个时候没有连接


可能是你运行平台上打印缓冲的问题吧
foochow 2008-11-10
  • 打赏
  • 举报
回复
行缓存
xhs_lh04 2008-11-10
  • 打赏
  • 举报
回复
怎么说
wuliangyue7 2008-11-10
  • 打赏
  • 举报
回复
测试用的client (虽然不是非阻塞的)发个消息接收一个数据

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <pthread.h>
#include <arpa/inet.h>

#define MAXDATASIZE 100 /*¨°?¡ä??¨¹?¨®¨º?¦Ì?¡Á?¡ä¨®¡Á??¨²¨ºy*/

int main(int argc,char *argv[])
{
int sockfd,numbytes,port;
char buf[MAXDATASIZE];
char msg[MAXDATASIZE];
struct hostent *he;
struct sockaddr_in their_addr;
if(argc!=3)
{
fprintf(stderr,"usage:client hostname port\n");
exit(1);
}
if((he=gethostbyname(argv[1]))==NULL)
{
herror("gethostbyname");
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
port=atoi(argv[2]);
their_addr.sin_family=AF_INET;
their_addr.sin_port=htons(port);
/*their_addr.sin_addr=(struct in_addr *)malloc(sizeof(struct in_addr));*/
their_addr.sin_addr=*((struct in_addr *)(he->h_addr_list[0]));
/*their_addr.sin_addr.s_addr=((struct in_addr*)(he->h_addr))->s_addr;*/
bzero(&(their_addr.sin_zero),8);
if(connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==-1)
{
perror("connect");
exit(1);
}
while(1)
{
printf("client:");
scanf("%[^\n]",msg);
strcat(msg,"\n");
if(send(sockfd,msg,strlen(msg)+1,0)==-1)
{
perror("send");
exit(1);
}

if((numbytes=recv(sockfd,buf,MAXDATASIZE,0))==-1)
{
perror("recv");
exit(1);
}
buf[numbytes]='\0';
printf("server: %s\n",buf);
/* printf("client:");
scanf("%s",msg);
strcat(msg,"\n");
if(send(sockfd,msg,strlen(msg)+1,0)==-1)
{
perror("send");
exit(1);
}*/
}
close(sockfd);
return 0;
}

69,372

社区成员

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

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