《UNIX网络编程》之read_timeout实验
最近在做项目,需要做一个服务器和客户端的基于TCP的套接口网络编程,由于服务器端返回数据并不是那么的及时,因此,需要在客户端做些延迟,然后才能去读取数据,实验测试结果如下。
首先,我们先来看一下我们封装好的一个读延时函数:
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
}while() /**
* read timeout - 读超时检测函数,不含读操作
* @fd: 文件描述符
* @wait_seconds: 等待超时秒数,如果为0标识不检测超时
* 成功(未超时)返回0, 失败返回-1, 超时返回-1并且errno = ETIMEOUT
*/
int read_timeout(int fd, unsigned int wait_seconds)
{
int ret;
if(wait_seconds > )
{
fd_set read_fdset;
struct timeval timeout; FD_ZERO(&read_fdset);
FD_SET(fd, &read_fdset); timeout.tv_sec = wait_seconds;
timeout.tv_usec = ; do
{
ret = select(fd + , &read_fdset, NULL, NULL, &timeout);
}while(ret < && errno == EINTR); if(ret == )//fail
{
//time out.
ret = -;
errno = ETIMEDOUT;
}
else if(ret == )//success
{
ret = ;
}
}
return ret;
}
下面,我们介绍如何使用该函数,伪代码如下:
int ret = read_timeout(sockfd, 15);
if(ret == 0)
{
readnum = read(sockfd, recvbuff, sizeof(recvbuff));
}
else if(ret == -1 && errno == ETIMEDOUT)
{
//time out dealing.
}
好,现在继续看我的服务器与客户端程序:
服务器
void str_echo(int sock)
{
ssize_t n;
char buff[]; again:
while( (n = read(sock, buff, sizeof(buff))) > )
{
fputs(buff, stdout);
sleep();//for testing client read_timeout
write(sock, buff, n);
}
if(n < && errno == EINTR)
{
goto again;
}
else if(n < )
{
ERR_EXIT("read");
}
} int main()
{
int listenfd, connfd;
pid_t childpid;
socklen_t clilen;
struct sockaddr_in servaddr, cliaddr; if( (listenfd = socket(AF_INET, SOCK_STREAM, )) < )
{
ERR_EXIT("socket");
} memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(); if((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < )
{
ERR_EXIT("bind");
} if( (listen(listenfd, SOMAXCONN)) < )
{
ERR_EXIT("listen");
} for(;;)
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);
if(connfd < )
{
ERR_EXIT("connect");
} if( (childpid = fork()) == )
{
//child
close(listenfd);
str_echo(connfd);
exit();
}
else
{
//parent
close(connfd);
} }
}
客户端
void str_cli(int sock)
{
char sendbuff[];
char recvbuff[]; memset(sendbuff, , sizeof(sendbuff));
memset(recvbuff, , sizeof(recvbuff));
int ret = -; //ssize_t n;
while(fgets(sendbuff, sizeof(sendbuff), stdin) != NULL)
{
write(sock, sendbuff, strlen(sendbuff)); ret = read_timeout(sock, );
if(ret == )
{
read(sock, recvbuff, sizeof(recvbuff));
}
else if(ret == - && errno == ETIMEDOUT)
{
ERR_EXIT("read_timeout");
}
fputs(recvbuff, stdout);
}
} int main(int argc, char **argv)
{ int sockfd;
struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(); sockfd = socket(AF_INET, SOCK_STREAM, );
if(sockfd < )
{
ERR_EXIT("socket");
} if( (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) < )
{
ERR_EXIT("connect");
} str_cli(sockfd);
return ;
}
例子一:
服务器延时3s, 客户端read_timeout(socd, 5);结果为:成功
《UNIX网络编程》之read_timeout实验的更多相关文章
- 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)
RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三 多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...
- 【Linux/unix网络编程】之使用socket进行TCP编程
实验一 TCP数据发送与接收 [实验目的] 1.熟练掌握套接字函数的使用方法. 2.应用套接字函数完成基本TCP通讯,实现服务器与客户端的信息交互. [实验学时] 4学时 [实验内容] 实现一个服务器 ...
- unix网络编程环境搭建
unix网络编程环境搭建 网络编程 环境 1.点击下载源代码 可以通过下列官网中的源代码目录下载最新代码: http://www.unpbook.com/src.html 2.解压文件 tar -xz ...
- UNIX网络编程——getsockname和getpeername函数
UNIX网络编程--getsockname和getpeername函数 来源:网络转载 http://www.educity.cn/linux/1241293.html 这两个函数或者 ...
- 20145211 《Java程序设计》实验报告五————Java网络编程及安全实验报告
实验内容 1.掌握Socket程序的编写: 掌握密码技术的使用: 设计安全传输系统. 实验步骤 这一部分是与我的partner合作的,详见他的博客- [20145326 <Java程序设计> ...
- Unix网络编程--卷二:进程间通信
Unix网络编程--卷二:进程间通信 本书是一部Unix网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机网络应用程序的必要条件.本书从对Po ...
- Unix网络编程--卷一:套接字联网API
UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...
- [转载] 读《UNIX网络编程 卷1:套接字联网API》
原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...
- UNIX网络编程
UNIX网络编程--socket的keep http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html
随机推荐
- eclipse/myeclipse 变量名自动补全问题
原理是:在输入变量名后,去掉按下空格或=后,代码上屏 以前只知道alt+/调出assist,后来发现可以所有字母都激活content assist(8.1里有写).用起来果然很爽,但是eclipse ...
- 【USACO 2.3.5】控制公司
[题目描述] 有些公司是其他公司的部分拥有者,因为他们获得了其他公司发行的股票的一部分.例如,福特公司拥有马自达公司12%的股票.据说,如果至少满足了以下三个条件之一,公司A就可以控制公司B了: 公司 ...
- Java学习----构造方法的重载
一个类中有多个同名的参数不一样(参数的个数,参数的类型,参数的顺序)的构造方法 public class Student { public Student() { System.out.println ...
- 网易DBA私享会分享会笔记1
1.mysql生态+DBA职业发展世界范围流行的开源关系型的数据库关系型数据库:mysql,oracle,sql server,access,postgresql,sqlite,sybase,info ...
- JS浮点数运算Bug
JS浮点数运算Bug的解决办法(转) 37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.0849999 ...
- Java基础学习第一天
================每日必读==================== 写代码: 1.明确需求.我需要实现什么需求? 2.分析思路.我需要怎么实现需求? 3.确定步骤.我的每一部分思路需要使 ...
- Gradle sync failed: Gradle version 2.2 is required. Current version is 2.10.
Gradle sync failed: Gradle version 2.2 is required. Current version is 2.10. If using the gradle wra ...
- 用UNetbootin来安装USB LINUX,好像比ULTRA ISO省事
UNetbootin can create a bootable Live USB drive, or it can make a "frugal install" on your ...
- (转载)PHP mb_substr函数在实际编码中的应用方法
(转载)http://developer.51cto.com/art/200912/166080.htm 我们在使用PHP语言进行实际编码中时,通常会遇到许多错误的出现,比如在截取字符串时会出现乱码等 ...
- 怎样在WIN7系统下安装IIS和配置ASP(详细)
一:Windows7系统 (IIS是WIN7自带的,版本7.0),首先是安装IIS.打开控制面板,找到“程序与功能”,点进去,点击左侧“打开或关闭Windows功能”,找到“Internet 信息服务 ...