《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
随机推荐
- iOS开发中EXC_BAD_ACCESS的另类原因
今天偶然学习iOS开发的时候碰到一个EXC_BAD_ACCESS的异常,经查资料得到的解释是由于访问了已经被回收了堆内存对象导致的,参考: http://code.tutsplus.com/tutor ...
- UIGestureRecognizer手势识别
UIGestureRecognizer 1.#import "ViewController.h"2.3.@interface ViewController ()<UIGest ...
- jQuery 的ready事件和 JavaScript 的load事件对比
为了理解2个事件的异同,先了解一下HTML文档加载顺序 HTML DOM文档加载步骤 HTML DOM文档加载是按顺序执行的,这与浏览器的渲染方式有关,一般浏览器渲染操作的顺序大致按如下几个步骤 1, ...
- nginx 伪静态大于10个参数 $10
伪静态大于10个参数 会解析成 $1 与 0 参考:http://zhidao.baidu.com/link?url=kT2tp8ARhIZsrt4XF3LdzjkEq0QTIbvhOj9Ck ...
- python运维开发之第三天
一.第二天课程的复习总结 1.列表可以增删改查,元组是不可修改的列表,字符串是不可以修改的. 2.列表,元组是有序的,字典是无序的,字典的key唯一 3.列表字典可以嵌套列表,可以嵌套字典,可以嵌套多 ...
- C语言基础学习运算符-逻辑运算符
逻辑运算符 逻辑运算符是根据表达式的值来返回真值或是假值.C语言中的逻辑运算符就三种,如下表所示: 列如: 更多学习内容,就在码芽网http://www.mayacoder.com/lesson/in ...
- Aptana Studio 快捷键
窗口 Ctrl+ Shift +L 调出快捷键提示 Ctrl+ W 关闭当前标签窗口 Ctrl+ Shift + W 关闭当前标签窗口 Ctrl+ F6 (或者是Aptana的Ctrl+Tab )下一 ...
- Js监控回车事件
标题通俗的说,也就是绑定当用户按下回车键要执行的事件. 下面,入正题. 第一步,先编写简单的页面代码,这里我们只需要一个按钮就足够了.当然,还有按钮事件. <html> <head& ...
- 《30天自制操作系统》读书笔记(2)hello, world
让系统跑起来 要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实 ...
- 转:微博CacheService架构浅析
文章来自于:http://www.infoq.com/cn/articles/weibo-cacheservice-architecture 微博作为国内最大的社交媒体网站之一,每天承载着亿万用户的服 ...