UNIX网络编程中的需要注意的问题
字节流套接字上调用read或write,输入或输出的字节数可能比请求的数量少,这个现象的原因在于内核中用于套接字的缓冲区可能已经达到了极限。此时所需要的是调用者再次调用read或write函数。这个现象在read()一个字节流套接字时很常见,但是在write()一个字节流套接字时只能在该套接字为非阻塞的前提下才出现。
connect()函数
1)若客户没有收到SYN分节的响应,则返回ETIMEDOUT错误;
2)若对客户的SYN响应是RST,则表明服务器在指定的端口上没有进程在等待与之连接,客户一接收到RST就马上返回ECONNREFUSED错误;
3)若客户发出的SYN在中间的路由器上引发了一个ICMP目的不可达错误,则间隔一定时间重新发送,若未收到响应,则返回EHOSTUNREACH或ENETUNREACH错误;
4)若connect()失败则该套接字不再可用,必须关闭,不能再对该套接字再次调用connect()函数。listen()函数
内核为任何一个给定的监听套接字维护两个队列:未完成连接队列,已完成连接队列。当一个客户SYN到达时,若这些队列是满的,TCP就忽略该分节,也就是不发送RST。accept()函数
已完成连接队列中的队头项将返回给进程,或者如果该列队为空,那么进程将被投入睡眠,直到TCP在该队列中放入一项才唤醒它。close()函数
close()一个TCP套接字的默认行为是把该套接字标记成已关闭,然后立即返回到调用进程,该套接字描述符不能再由调用进程使用,然而TCP将尝试发送已排队等待发送到对端的任何数据,发送完毕后发生的是正常的TCP连接终止序列。当fork子进程时,必须捕获SIGCHLD信号。在Linux中,每个信号都有一个预定义的默认行为,它们是下面的一种:进程忽略该信号、进程终止、进程终止并转储存储器、进程停止直到被SIGCONT信号重启。而最好的处理SIGCHLD信号的方式是在信号处理函数中调用
while((pid = waitpid(-1, &status, WNOHANG)) > 0);
,而不是调用wait()。当信号是在父进程阻塞于慢系统调用时由父进程捕获的,内核就会使系统调用返回一个EINTR错误,我们必须判断并处理该错误,如当父进程调用accept()时,子进程发送SIGCHLD信号。
当执行kill命令杀死服务器进程时,服务器进程会向客户发送一个FIN,而客户响应一个ACK,这就是TCP连接终止工作的前半部分。当客户再向服务器发送数据时,服务器会响应一个RST,当客户再向这个响应RST的套接字执行写操作时,内核向该进程发送一个SIGPIPE信号。
当服务器主机崩溃,即服务器突然从网络上断开,这时向服务器发送数据,服务器对客户的数据分节根本没有响应,返回的错误将是ETIMEDOUT,如果某个中间路由器返回ICMP目的不可达信息,返回的错误将是EHOSTUNREACH或ENETUNREACH错误。
当服务器主机崩溃后重启,即断开服务器网络,再重新启动,最后再把它接入网络,服务器会对所有收到来自客户的数据分节响应一个RST。
当服务器主机关机时,init进程通常先给所有进程发送SIGTERM信号,等待一段固定时间,然后给所有仍在运行的进程发送SIGKILL信号,服务器上所有打开着的描述符都被关闭。
检测各种TCP条件的方法
close()有两个限制可以使用shutdown()来避免。close()仅在引用计数变为0时才关闭套接字,而使用shutdown()可以不管引用计数就激发TCP的正常连接终止序列;close()终止读写两个方向的数据传送,而shutdown()可以根据参数选择终止。
SO_KEEPALIVE套接字选项
如果2小时内在该套接字的任一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节。
对端可能发生的动作有3种,1)响应ACK;2)响应RST(套接字的待处理错误被置为ECONNRESET,套接字本身被关闭);3)无任何响应(共发送8个探测分节,如果根本没有对TCP的探测分节的响应,该套接字的待处理错误就被置为ETIMEDOUT,套接字本身被关闭)。SO_LINGER套接字选项
指定close()对面向连接的协议如何操作。shutdown和SO_LINGER各种情况总结如下。
SO_REUSEADDR套接字选项
1)允许启动一个监听服务器并捆绑其众所周知的端口,即使以前建立的将该端口用作它们的本地端口连接仍存在;
2)允许在同一个端口上启动同一个服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可;
3)允许单个进程捆绑同一端口到多个套接字上,只要每次捆绑指定不同的本地IP地址即可,TCP服务器通常不使用这种方法;
4)允许完全重复的捆绑,同样的IP地址和端口还可以捆绑到另一个套接字上,一般来说本特性仅支持UDP套接字。TCP_NODELAY套接字选项
开启本选项将禁止TCP的Nagle算法,Nagle算法常常与ACK延滞算法联合使用。该算法是指发送端即使还有应该发送的数据,但如果这部分数据很少的话,则进行延迟发送的一种处理机制。具体来说,就是公在下列任意一种条件下才能发送数据,如果两个条件都不满足,那么暂时等待一段时间以后再进行数据发送。
1)已发送的数据都已经收到确认应答时;
2)可以发送最大长度(MSS)的数据时。UDP的connect()函数
对于已连接UDP套接字,与默认的示连接UDP套接字相比,发生了三个变化:
1)不能给输出操作指定目的IP地址和端口号,不使用sendto(),改用write()或send();
2)不必使用recvfrom()以获悉数据报的发送者,而改用read()、recv()或recvmsg();
3)由已连接UDP套接字引发的异步错误会返回给它们所在的进程,而未连接UDP套接字不接收任何异步错误。
参考:《UNIX网络编程》。
UNIX网络编程中的需要注意的问题的更多相关文章
- Unix网络编程中的五种I/O模型_转
转自:Unix网络编程中的的五种I/O模型 下面主要是把unp第六章介绍的五种I/O模型. 1. 阻塞I/O模型 例如UDP函数recvfrom的内核到应用层.应用层到内核的调用过程是这样的:首先把描 ...
- UNIX网络编程中的字节序问题
1.inet_pton 函数原型: inet_pton:将“点分十进制” -> “二进制整数” int inet_pton(int af, const char *src, void *dst) ...
- UNIX网络编程读书笔记:简介
认知套接口编程接口 理解原始套接口(raw socket)的概念 值得注意的是,客户和服务器是典型的用户进程,而TCP和IP协议则通常是系统内核协议栈的一部分. 上图中在TCP和UDP之间留有间隙 ...
- unix 网络编程 第五章
个人对unix 网络编程中的代码进行了精简,保留了主要和关键部分. 1 tcpserve01 程序见 https://github.com/juniperdiego/Unix-network-prog ...
- unix网络编程str_cli使用epoll实现
unix网络编程str_cli使用epoll实现 unix环境高级编程中也有这个函数,都是为了讲解IO多路转接.从本质上来看epoll就是一个改善了的select和poll,本质没发生任何变化,对于构 ...
- UNIX网络编程——getsockname和getpeername函数
UNIX网络编程--getsockname和getpeername函数 来源:网络转载 http://www.educity.cn/linux/1241293.html 这两个函数或者 ...
- 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)
RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...
- 浅谈TCP/IP网络编程中socket的行为
我认为,想要熟练掌握Linux下的TCP/IP网络编程,至少有三个层面的知识需要熟悉: 1. TCP/IP协议(如连接的建立和终止.重传和确认.滑动窗口和拥塞控制等等) 2. Socket I/O系统 ...
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)
RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三 多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...
随机推荐
- 5个简单的步骤把 WordPress 打造成 CMS
可能网站的首页一直是一成不变的博客样子,有时候也会挺闷的,个人觉得首页就是应该把博客中最好最重要的内容展现给读者,基于这个想法,我们可以把博客的首页改成一个非常简单的 CMS 首页. 基于 WordP ...
- USACO 1.3.1
题目链接:USACO 1.3.1 简单的贪心,将cent从小到大排序. /* ID:wang9621 PROG:milk LANG:C++ */ #include <iostream> # ...
- pthread_join
摘要:pthread_join使一个线程等待另一个线程束. 代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了.加入pthread_jo ...
- shell vim--处理二进制文本
1 使用vim -b :%!xxd 参考:http://www.cnblogs.com/killkill/archive/2010/06/23/1763785.html 2 使用xxd命令 htt ...
- C缺陷与陷阱----读书笔记---第一章
第一章:词法陷阱 编译器中负责将程序分解为一个一个符号的部分,一般称为“词法分析器”.例如,对于语句: if ( x == big ) big = x ; 它的第一个符号是C语言关键字if,紧接着下一 ...
- RabbitMQ java 参数
channel.exchangeDeclare(exchange, "direct", true, false, null); 第一个参数:交换组名字, 第二个参数:队交换组类型: ...
- 10.8.5如何升级(app store 出错 请稍后重试 100)
出现问题:苹果以前的老版本,OS X 10.8或是10.8.5在当年提示你升级,你又任性没升级的时候,拖过那阵,你再想升级,就是各种报复.进app store下载或是更新东西都是弹出app stpre ...
- NSCalendar 日历类
NSCalendar 日历类 Cocoa中对日期和时间的处理 NSCalendar (一) (2008-11-12 21:54:10) NSCalendar用于处理时间相关问题.比如比较时间前后.计算 ...
- CentOS6.x升级MySQL版本5.1到5.6
CentOS6.x升级MySQL版本5.1到5.6 分类: Web MySQL 2014-08-04 11:22 2813人阅读 评论(1) 收藏 举报 mysql云服务器升级centos6 有一些虚 ...
- 微信小程序登录
一. 小程序不支持cookie会话 1. 通过传递与检验3rd_session来保持会话 2. 3rd_session可以执行'`head -n 80 /dev/urandom | tr -dc A- ...