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编程(如下图)中调用如下 ...
随机推荐
- Linux下设置MySQL不区分大写和小写
MySQL在Linux下数据库名.表名.列名.别名大写和小写规则: 1.数据库名与表名是严格区分大写和小写 2.表的别名是严格区分大写和小写 3.列名与列的别名在全部的情况下均是 ...
- Docker基础(一)
1.安装:安装教程很多,Ubuntu14.04安装比较简单docker[之前使用Ubuntu13.04结果安装了好久也没有安装好,后来就直接是14,04了] 2.docker是容器,那么什么是容器? ...
- (转载)iis7下站点日志默认位置
转自http://www.cnblogs.com/mincyw/p/3425468.html iis7下站点日志默认位置 在iis6时,通过iis管理器的日志配置可以找到站点日志存储的位置. 但是 ...
- linux 安装完mysql 密码重置
If you have forgot the MySQL root password, can’t remember or want to break in….. you can reset them ...
- jquery如何实现点击标题收缩下面的内容
jquery如何实现点击标题收缩下面的内容 一.总结 一句话总结:怎么做复杂前端任务,先把样式(最简单)做出来,然后在写js. 1.如何取jquery集合中的某个索引号的元素? 不是get(),是eq ...
- swift学习第五天:字符串
字符串的介绍 字符串在任何的开发中使用都是非常频繁的 OC和Swift中字符串的区别 在OC中字符串类型时NSString,在Swift中字符串类型是String OC中字符串@"" ...
- 用户之间imp的问题
今天同事说申请了一个从生产导出的dump文件,须要导入測试库进行測试. 之前做的基本都是本库导出,本库导入的操作,比如:imp test/***@test tables=tbl_fuel file=H ...
- 走进windows编程的世界-----对话框、文本框、button
1 对话框的分类 2 对话框的基本使用方式 3 对话框资源 4 有模式对话框的使用 int DialogBox( HINSTANCE hInstance, LPCTSTR lpTemplate, ...
- #308 (div.2) B. Vanya and Books
1.题目描写叙述:点击打开链接 2.解题思路:本题要求统计数位的个数,简单的试验一下发现有例如以下规律:一个n位数的个数有9*(10^n)个.因此全部n位数的数位是n*9*(10^n)个.因此能够利用 ...
- VMWare提供三种工作模式桥接(bridge)、NAT(网络地址转换)和host-only(主机模式)
1.桥接模式 在桥接模式下,VMWare虚拟出来的操作系统就像是局域网中的一台独立的主机(主机和虚拟机处于对等地位),它可以访问网内任何一台机器.在桥接模式下,我们往往需要为虚拟主机配置IP地址.子网 ...