scoket 在linux下C语言怎么设置read超时?

zljjava 2012-03-26 10:54:33
scoket 在linux下C语言怎么设置read超时?
在下刚接触C语言,求高手解决怎么设置scoket,read超时(不是connnect 超时)
贴下代码,感激不尽......
...全文
1317 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
zljjava 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wallwind 的回复:]

不是有个超时的参数么?
[/Quote]
超时的参数我设置的是5秒 应该没有问题吧?
是不是我最后不应该再设置为阻塞模式啊?
wintree 2012-03-26
  • 打赏
  • 举报
回复
不是有个超时的参数么?
sundayX 2012-03-26
  • 打赏
  • 举报
回复
select是这样用的么?
你得判断FD_ISSET
zljjava 2012-03-26
  • 打赏
  • 举报
回复
int writeToserve(char *str, char *output) {
//server
struct sockaddr_in servaddr;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr);
servaddr.sin_port = htons(SERVER_PORT);

int sockfd, n;
char buf[MAXLINE];
//create scoket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd) {
printf("scoket---fail%s\n");
writeLog("scoket---fail");
close(sockfd);
return 1;
}
//connect

int error = -1, len;
len = sizeof(int);
struct timeval tm;
fd_set set;

unsigned long ul = 1;
ioctl(sockfd, FIONBIO, &ul); //设置为非阻塞模式
int ret = 1; //

if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))
== -1) {
printf("connect === -1!!!\n");
tm.tv_sec = TIME_OUT_TIME;
tm.tv_usec = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
if (select(sockfd + 1, NULL, &set, NULL, &tm) > 0) {
printf("select > 0\n");
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error,
(socklen_t *) &len);
if (error == 0)
ret = 0;
else
ret = 1;
} else
ret = 1;
} else
ret = 0;
//====================================






write(sockfd, str, strlen(str));
n=read(sockfd, buf, MAXLINE);
printf("n===============%d\n",n);
printf("ret===============%d\n",ret);

if (ret != 0 ) {
close(sockfd);
printf("Cannot Connect the server!\n");
writeLog("Cannot Connect the server!\n");
return 1;
}
ul = 0;
ioctl(sockfd, FIONBIO, &ul); //设置为阻塞模式

bzero(buf, MAXLINE);
strcpy(output, buf);
close(sockfd);
return 0;
}



这是我写的代码,把read()放在非阻塞模式里,但是server端是有返回信息的,为什么运行之后是output是空的?
sundayX 2012-03-26
  • 打赏
  • 举报
回复
select方式
qiuhui00 2012-03-26
  • 打赏
  • 举报
回复
打开socket描述符后,过程类似以下这样
fd_set rset;
struct timeval tv;
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
tv.tv_sec = 10;//超时时间
tv.tv_usec = 0;

select(sockfd + 1, &rset, NULL, NULL, &tv)
zljjava 2012-03-26
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fishion 的回复:]

在linux下用select比较多
[/Quote]
请问是和connnect 用select 超时一样的吗?
能不能贴点代码,谢了....
fishion 2012-03-26
  • 打赏
  • 举报
回复
在linux下用select比较多
  • 打赏
  • 举报
回复
可以用非阻塞方式配合select实现超时
qq120848369 2012-03-26
  • 打赏
  • 举报
回复
       SO_RCVTIMEO and SO_SNDTIMEO
Specify the receiving or sending timeouts until reporting an error. The parameter is a struct timeval. If an input or output function blocks for this
period of time, and data has been sent or received, the return value of that function will be the amount of data transferred; if no data has been
transferred and the timeout has been reached then -1 is returned with errno set to EAGAIN or EWOULDBLOCK just as if the socket was specified to be non-
blocking. If the timeout is set to zero (the default) then the operation will never timeout.
景语 2012-03-26
  • 打赏
  • 举报
回复
使用setsockopt函数设置,非阻塞IO,可以使得在指定时间未收到数据后自动跳出。

你可以查阅查一查这个函数的参数及用法。
非常简单。
nanjingnew4 2012-03-26
  • 打赏
  • 举报
回复
给你一段我写的client代码

/*客户端*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netdb.h>
#include<netinet/in.h>
#include<unistd.h>
#include<sys/time.h>
#include <errno.h>

#define SERVERPORT 5556

int main(int argc,char *argv[])
{
int sockfd,connectfd=0,recvfd,sendfd ;
struct sockaddr_in serv_addr;
struct hostent *host;
FILE *fp;
char ch[1024];
int byte_send=0;
//int a=MSG_DONTWAIT;
//int opt=MSG_DONTWAIT;
fd_set rfds;
struct timeval tv;
int retval, maxfd;

if(argc!=3)
{
printf("format: %s IP file_name\n",argv[0]);
return 0;
}

if((host=(gethostbyname(argv[1])))==NULL)
{
printf("error in gethostby name. \n");
return 0;
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("error in socket create.\n");
return 0;
}
printf("创建socket成功,sockfd=%d\n",sockfd);
//printf("运行至此1\n");
serv_addr.sin_family=AF_INET;
serv_addr.sin_port =htons(SERVERPORT);
serv_addr.sin_addr=*((struct in_addr*)host->h_addr);
bzero(&(serv_addr.sin_zero),sizeof(serv_addr.sin_zero));
//printf("运行至此2\n");
while(1)
{
if((connectfd=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr )))==-1)
{
printf("error in connect.\n");
printf("连接失败:connectfd=%d\n",connectfd);
sleep(5);
continue;
}
printf("连接成功:connectfd=%d\n",connectfd);
break;

}
//printf("运行至此3\n");
fp=fopen(*(argv+2),"rb");
memset(ch,0,sizeof(ch));
while(1)
{
memset(ch,0,sizeof(ch));
sendfd=fread(ch,sizeof(char),1024,fp);
if(sendfd<0)
break;
sleep(1);
//printf("sendfd=%d\n",sendfd);
byte_send=send(sockfd,ch,sendfd,0);
//printf("byte_send=%d,%s\n",byte_send,strerror(errno));
//memset(&ch,0,sizeof(ch));
//printf("发送内容:%s\n",ch);
sleep(3);
while(1)
{
//void FD_ZERO (fd_set *fdset); // 初始化文件描述集合  
//void FD_SET (int fd, fd_set *fdset); // 将描述符加入到集合中  
//void FD_CLR (int fd, fd_set *fdset); // 将描述符中集合中删除  
//int FD_ISSET (int fd, fd_set *fdset); // 检查描述符集合中指定的文件描述符是否可读写
/*把可读文件描述符的集合清空*/
FD_ZERO(&rfds);
/*把标准输入的文件描述符加入到集合中*/
FD_SET(0, &rfds);
maxfd = 0;
/*把当前连接的文件描述符加入到集合中*/
FD_SET(sockfd, &rfds);
/*找出文件描述符集合中最大的文件描述符*/
if(maxfd < sockfd)
maxfd = sockfd;
/*设置超时时间*/
tv.tv_sec = 5;
tv.tv_usec = 0;
/*等待聊天*/
retval = select(maxfd+1, &rfds, NULL, NULL, &tv);
if(retval == -1)
{
printf("select出错,客户端程序退出\n");
break;
}
else if(retval == 0)
{
//printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");
//continue;
printf("客户端输出信息完毕,等待下一次输出\n");
break;
}
else
{
/*服务器发来了消息*/
if(FD_ISSET(sockfd,&rfds))// 检查描述符集合中指定的文件描述符是否可读写
{
/******接收消息*******/
memset(ch,0,sizeof(ch));
recvfd=recv(sockfd,ch,sizeof(ch),0);
if(recvfd==-1)
{
//printf("运行至此7\n");
printf("error in recv.\n");
continue;
}
//printf("recvfd=%d\n",recvfd);
printf("%s\n",ch);
}
}

}

}

printf("传送结束!\n");
fclose(fp);
close(connectfd);
return 0;
}




69,373

社区成员

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

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