Linux 网络编程——TCP
.png)

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h> int main(int argc, char *argv[])
{
int fd;
struct sockaddr_in addr;
struct timeval timeo = {3, 0};
//lingger参数1表示启用linger,5最多等待5秒或者socket发送队列中的消息发送完毕
//再执行close操作
struct linger linger_value = {1, 5};
socklen_t len = sizeof(timeo); //创建TCP连接,SOCK_CLOEXEC指明在执行fork等创建子进程函数时,子进程将继承的该fd描述符默认关闭
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (argc == 4)
timeo.tv_sec = atoi(argv[3]); //设置接受socket数据的等待时间,对read,recv,recvfrom等函数生效
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, len); //设置该参数是为了保证在关闭前尽可能的将数据都发送出去
setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger_value, (socklen_t)sizeof(linger_value)); addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(atoi(argv[2])); //connect受SO_SNDTIMEO设置影响,最多等待timeo时间
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
if (errno == EINPROGRESS) {
fprintf(stderr, "timeout\n");
return -1;
}
perror("connect");
return -1;
}
printf("connected\n"); char *msg = "hello buddy !";
//这里指定MSG_NOSIGNAL表示当fd已经关闭时,不会触发SIGPIPE信号(该信号的默认操作是关闭程序
send(fd, msg, strlen(msg), MSG_NOSIGNAL); char buffer[1024] = {'\0'};
//这里的MSG_DONTWAIT就是要求recv函数非阻塞执行 ,同给socket设置SO_NONBLOCK效果一样
recv(fd, buffer, sizeof(buffer) - 1, MSG_NOSIGNAL | MSG_DONTWAIT); //向对端发送FIN报文,关闭该fd上所有的读写socket连接
shutdown(SHUT_RDWR, fd); //关闭文件描述符,如果执行了fork函数且没有设置SOCK_CLOEXEC,需要在子进程中也执行close关闭继承的文件描述符
close(fd); return 0;
}
注:该代码是客户端的一部分代码,服务端与这个类似,区别就是服务端用bind、listen、accept函数替代了connect函数来实现对服务端口的监听、新连接的处理。
- 编写多进程程序时,如果创建文件描述符(打开文件、创建socket等)都需要设置SOCK_CLOEXEC标识,避免出现副作用。
- 给socket设置SO_LINGER选项、调用close之前执行shutdown命令一般用于服务端,这样可以最大限度地保证将数据发送到客户端并且可以有效防止,因为fork导致的子进程在处理socket时调用close关闭fd描述符,由于fd原有计数是2,所以fd并未实际关闭,也就不会触发向客户端发送FIN报文结束连接的动作。因而,服务端就可能出现大量的CLOSE_WAIT的连接。
- 如果系统收到FIN报文,会让recv、read等函数返回0表示连接已经关闭。此时send、recv等读写函数再对目标fd进行读写,根据TCP协议规定,会收到一个RST报文,如果再读写的话系统就会发送SIGPIPE信号给调用进程,而该信号默认动作是结束进程。因此,要么调用信号处理函数将SIGPIPE捕获处理,要么像代码中那样设置MSG_NOSIGNAL选项避免产生SIGPIPE信号。
- SO_SNDTIMEO除了对send、write等有效外,还对connect有效;SO_RCVTIMEO除了对recv、read等有效外还对accept有效。
- 如果系统中出现大量的close_wait状态的TCP连接,说明是程序在收到对端的FIN报文后没有关闭相关的socket(有可能是fork这类函数造成的),这需要检查结束连接处理部分的代码。
- 如果系统中出现大量的time_wait状态的TCP连接,这种连接是正常的。出现这种连接都是由于主动关闭socket造成的,解决方案就是改成客户端主动结束连接、或者降低time_wait的时间。
Linux 网络编程——TCP的更多相关文章
- Linux网络编程——tcp并发服务器(poll实现)
想详细彻底地了解poll或看懂下面的代码请参考<Linux网络编程——I/O复用之poll函数> 代码: #include <string.h> #include <st ...
- Linux网络编程-tcp缓存设置
最近发现服务的逻辑完成时间很短,但是上游接收到的时间比较长,所以就怀疑是底层数据的序列化/反序列化.读写.传输有问题,然后怀疑是TCP的读写缓存是不是设置太小.现在就记录下TCP缓存的各配置项以及缓存 ...
- linux网络编程tcp
之前学习的时候笔记没有保存好,这次重新编写一个案例. 客户端实现程序代码: #include <string.h> #include <stdlib.h> #include & ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
- 【Linux网络编程】TCP网络编程中connect()、listen()和accept()三者之间的关系
[Linux网络编程]TCP网络编程中connect().listen()和accept()三者之间的关系 基于 TCP 的网络编程开发分为服务器端和客户端两部分,常见的核心步骤和流程如下: conn ...
- TCP/UDP Linux网络编程详解
本文主要记录TCP/UDP网络编程的基础知识,采用TCP/UDP实现宿主机和目标机之间的网络通信. 内容目录 1. 目标2.Linux网络编程基础2.1 嵌套字2.2 端口2.3 网络地址2.3.1 ...
- 【深入浅出Linux网络编程】 "开篇 -- 知其然,知其所以然"
[深入浅出Linux网络编程]是一个连载博客,内容源于本人的工作经验,旨在给读者提供靠谱高效的学习途径,不必在零散的互联网资源中浪费精力,快速的掌握Linux网络编程. 连载包含4篇,会陆续编写发出, ...
- 【linux草鞋应用编程系列】_5_ Linux网络编程
一.网络通信简介 第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章. 二.linux网络通信 在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...
- Linux 网络编程(IO模型)
针对linux 操作系统的5类IO模型,阻塞式.非阻塞式.多路复用.信号驱动和异步IO进行整理,参考<linux网络编程>及相关网络资料. 阻塞模式 在socket编程(如下图)中调用如下 ...
随机推荐
- PHP与Linux进程间的通信
进程间通信预计是公司考察应届毕业生的必考点(嵌入式行业).当然非常多公司考的是算法. 不查阅资料,我脑子里能想到的 [1] 管道, (有名.无名) [2] 父子进程 [3] System V (消息队 ...
- JSF教程(11)——生命周期之Invoke Application Phase
在这个阶段JSF实现将处理不论什么应用界别的事件,比如表单的提交或者链接点击后跳转到还有一个页面. 这时假设应用须要重定向不同 的web应用字眼或者产生一个资源其并不喊不论什么的JSF组件,那么就调用 ...
- MAVEN Error: Using platform encoding (GBK actually) to copy filtered resources.....
环境:Maven3.2.5+MyEclipse 2015CI 现象:在Maven编译过程中出现错误信息:Using platform encoding (GBK actually) to copy f ...
- fatal error C1859的有效解决办法
作者:朱金灿来源:http://blog.csdn.net/clever101 在服务器(操作系统为Widows Server2008)上使用VS C++2008编译工程,总是出现这样一个错误:fat ...
- ocx 中使用CImage和CComPtr
#include <atlimage.h> using namespace ATL;
- PatentTips - Data Plane Packet Processing Tool Chain
BACKGROUND The present disclosure relates generally to systems and methods for providing a data plan ...
- js 字符串操作函数有哪些
js 字符串操作函数有哪些 一.总结 一句话总结:js字符串函数都是字符串对象的方法,是通过调用字符串方法的方式调用,和java,php里面不一样. 1.字符串替换函数怎么用? 这里的正则表示是加双引 ...
- js进阶ajax的XMLHttpRequest对象的status和statustext属性(如果ajax和php联合使用的话:open连接服务器的第二个参数文件路径改成请求php的url即可)
js进阶ajax的XMLHttpRequest对象的status和statustext属性(如果ajax和php联合使用的话:open连接服务器的第二个参数文件路径改成请求php的url即可) 一.总 ...
- java之 ------ 枚举类型
枚举 一.枚举类型具体说明 简单的说.Enum一般用来表示一组同样类型的常量. 如性别.日期.月份.颜色等.对这些属性用常量的优点是显而易见的,不仅能够保证单例,且在比較的时候能够用"==& ...
- Android多线程研究(9)——线程锁Lock
在前面我们在解决线程同步问题的时候使用了synchronized关键字,今天我们来看看Java 5.0以后提供的线程锁Lock. Lock接口的实现类提供了比使用synchronized关键字更加灵活 ...