【UNIX网络编程(二)】基本TCP套接字编程函数
基于TCP客户/server程序的套接字函数图例如以下:
运行网络I/O。一个进程必须做的第一件事就是调用socket函数。指定期望的通信协议类型。
#include <sys/socket.h>
int socket(int family, int type, int protocol);/*返回值:若成功则为非负描写叙述符,若出错则为-1*/
socket函数成功时返回一个小的非负整数值,它与文件描写叙述符类似。把它称为套接字描写叙述符,简称sockfd。family參数指明协议族。被称为协议域。type參数指明套接字类型。
protocol參数应该是某个协议类型常值。或者为0,以选择所给定family和type组合的系统默认值。
各參数列于一下表格:
family | 说明 | type | 说明 | protocol | 说明 |
AF_INET | IPv4协议 | SOCKET_STREAM | 字节流套接字 | IPPROTO_TCP | TCP传输协议 |
AF_INET6 |
IPv6协议 | SOCK_DGRAM | 数据报套接字 | IPPROTO_UDP | UDP传输协议 |
AF_LOCAL | Unix域协议 | SOCK_SEQPACKET | 有序分组套接字 | IPPROTO_SCTP | SCTP传输协议 |
AF_ROUTE | 路由套接字 | SOCK_RAM | 原始套接字 | ||
AF_KEY | 秘钥套接字 |
TCP客户用connect函数来建立与TCPserver的链接。
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen); /*返回:若成功则为0。若出错则为-1*/
sockfd是由socket函数返回的套接字描写叙述符。第二个、第三个參数各自是一个指向套接字地址结构的指针和该结构的大小。客户在调用函数connect前不必非得调用bind函数,由于假设须要的话,内核会确定源IP地址,并选择一个暂时port号作为源port。假设是TCP套接字,调用connect函数将激发TCP的三路握手过程,并且仅在连接建立成功或出错时才返回,当中出错返回可能有下面几种情况:
a、若TCP客户没有收到SYN分节的响应,则返回ETIMEDOUT错误。
b、若对客户的SYN的响应是RST(表示复位),则表明该server主机在我们指定的port上没有进程在等待与之连接。
c、若客户发出的SYN在中间的某个路由器上引发了一个“destination unreachable”ICMP错误。则觉得是一个软错误。
bind函数把一个本地协议地址赋予一个套接字。对于网际网协议,协议地址是32位的IPv4地址与16位的TCP或UDPport号的组合。
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);/*返回,成功则为0,出错则为-1*/
第二个參数是一个指向特定于协议的地址结构的指针。第三个參数是该地址结构的长度,对于TCP。调用bind函数能够指定一个port号。或指定一个IP地址,也能够两者都指定。还能够都不指定。
server在启动时捆绑它们的众所周知port。假设一个TCP客户或server未曾调用bind捆绑一个port,当调用connect或listen时。内核就要为对应的套接字选择一个暂时port号。让内核选择暂时port对于TCP客户来说是正常的。除非应用须要一个预留port;而毁于TCPserver来说却极为罕见,由于server是通过他们的众所周知port被大家认识的。
进程能够把一个特定的IP地址捆绑到它的套接字上,只是这个IP地址必须属于其所在主机的网络接口之中的一个。
假设指定port号为0,那么内核就bind被调用时选择一个暂时port。然而假设指定IP地址为通配地址。那么内核将等到套接字已连接TCP或已在套接字上发出数据报时才选择一个IP地址。对于IPv4来说,通配地址由常量INADDR_ANY来指定,其值为0。
注意:假设让内核来为套接字选择一个暂时port号,那么必须注意。函数bind并不返回所选择的值。实际上。因为bind函数的第二个參数有const限定词,它无法返回所选之值。
为了得到内核所选择的这个暂时port值,必须调用函数getsockanme来返回协议地址。
listen函数仅由TCPserver调用,它做两件事:
1、当socket函数创建一个套接字时,它被如果为一个主动套接字,也就是说。它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应该受指向该套接字的连接请求。
2、本函数的第二个參数规定了内核应该为对应套接字排队的最大连接个数。
#include <sys/socket.h>
int listen(int sockfd, int backlog);/*返回:若成功则为0。出错则为-1*/
本函数通常应该在调用socket和bind这两个函数之后。并在调用accept函数之前调用。
为理解backlog參数。必须认识到内核为不论什么一个给定的监听套接字维护两个队列:
1、未完毕连接队列。每一个这种SYN分节相应当中一项:已由某个客户发出并到达server,而server正在等待完毕相应的TCP三路握手过程,这些套接字处于SYN_RCVD状态
2、已完毕连接队列,每一个已完毕TCP三路握手过程的客户相应当中一项。这些套接字处于ESTBLISHED状态。
accept函数由TCPserver调用,用于从已完毕连接队列返回下一个已完毕连接。假设已完毕连接队列为空,那么进程被投入睡眠。
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen); /*返回:若成功则为负描写叙述符。若出错则为-1*/
參数cliaddr和addrlen用来返回已连接的对端进程协议地址。假设accept成功,那么其返回值是由内核自己主动生成的一个全新描写叙述符,代表与所返回客户的TCP链接。在讨论accept函数时,称第一个參数为监听套接字描写叙述符。称返回值为已连接套接字描写叙述符。区分这两个套接字很重要。
一个server通常只创建一个监听套接字,它在该server的生命周期内一直存在。
内核为每一个由server进程接受的客户连接创建一个已连接套接字。当server完毕对某个给定客户的服务时,对应的一两节套接字就被关闭。
本函数最多返回3个值:一个既可能是新套接字描写叙述符也可能是出错仅仅是的整数、客户进程的协议地址以及该地址的大小。假设对返回客户协议地址不感兴趣,能够把cliaddr和addrlen均置为空指针。
close函数用来关闭套接字。并终止TCP连接。int close(int sockfd)。返回:成功则为0。出错则为-1。
【UNIX网络编程(二)】基本TCP套接字编程函数的更多相关文章
- 【UNIX网络编程(四)】TCP套接字编程具体分析
引言: 套接字编程事实上跟进程间通信有一定的相似性,可能也正由于此.stevens这位大神才会将套接字编程与进程间的通信都归为"网络编程",并分别写成了两本书<UNP1> ...
- TCP套接字编程模型及实例
摘要: 本文讲述了TCP套接字编程模块,包括服务器端的创建套接字.绑定.监听.接受.读/写.终止连接,客户端的创建套接字.连接.读/写.终止连接.先给出实例,进而结合代码分析. PS:本文权当 ...
- UNP学习笔记1——基本TCP套接字编程
1 套接字地址结构 大多数套接字函数都需要一个指向套接字地址结构的指针作为参数.每个协议族都定义了自己的套接字结构.这些套接字的结构以sockaddr_开头,以每个协议族唯一的后缀名结尾. 1.1 I ...
- 【unix网络编程第三版】阅读笔记(二):套接字编程简介
unp第二章主要将了TCP和UDP的简介,这些在<TCP/IP详解>和<计算机网络>等书中有很多细致的讲解,可以参考本人的这篇博客[计算机网络 第五版]阅读笔记之五:运输层,这 ...
- unix网络编程——TCP套接字编程
TCP客户端和服务端所需的基本套接字.服务器先启动,之后的某个时刻客户端启动并试图连接到服务器.之后客户端向服务器发送请求,服务器处理请求,并给客户端一个响应.该过程一直持续下去,直到客户端关闭,给服 ...
- unix网络编程第四章----基于TCP套接字编程
为了执行网络I/O操作.进程必须做的第一件事情就是调用Socket函数.指定期待的通信协议 #include<sys/socket.h> int socket(int family,int ...
- 初探网络编程--TCP套接字编程演示
今天看了一下<计算机网络:自顶向下方法>,也就是计算机网络的教材的应用层一章,决定实现以下后面的Java C/S应用程序的例子,用来演示TCP和UDP套接字编程. 程序流程如下: 1.一台 ...
- <网络编程>基本TCP套接字编程
tcp提供了可靠传输,当tcp向另一端发送数据的时候,要求对端返回一个确认.如果没有接收到确认,tcp就重传数据并且等待更长时间,数次重传失败后,tcp才放弃. 建立一个tcp连接会发生如下事情: 服 ...
- 套接字编程相关函数(2:TCP套接字编程相关函数)
本文摘录自<UNIX网络编程 卷1>. 基本套接字函数 socket函数 为了执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型.其定义如下: #in ...
随机推荐
- Windows多线程同步系列之二-----关键区
关键区对象为:CRITICAL_SECTION 当某个线程进入关键区之后,其他线程将阻塞等待,知道该线程释放关键区的拥有权. 关键区同步主要有以下几个API 初始化关键区对象,无返回值,传入一个关键区 ...
- 剑指offer-面试题13.在O(1)时间删除链表节点
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 链表节点与函数的定义如下. 通常我们删除某个节点都是从头开始遍历到需要删除节点的前一个节点. 然后使得该节点的next ...
- CSS3初步
一.CSS与CSS3的区别 非常简单,CSS代表"Casading Style Sheets",就是样式表,是一种替代并为网站添加样式的标记性语言.现在所使用的CSS基本是在199 ...
- OC基础17:归档
"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.归档即是用某种格式把一个或多个对象保存 ...
- 在Swift中使用遗留的C API
Swift的类型系统的设计目的在于简化我们的生活,为此它强制用户遵守严格的代码规范来达到这一点.毫无疑问这是一件大好事,它鼓励程序员们编写 更好更正确的代码.然而,当Swift与历史遗留的代码库.特别 ...
- 如何测试sql语句性能,提高执行效率
有时候我们经常为我们的sql语句执行效率低下发愁,反复优化后,可还是得不到提高 那么你就用这条语句找出你sql到底是在哪里慢了 示例: SET STATISTICS io ON SET ...
- /boot磁盘空间不足,没盘扩展,只好删除旧内核了
[xiejdm@localhost ~]$ uname -r -.el7.x86_64 [xiejdm@localhost ~]$ sudo rpm -qa | grep kernel kernel- ...
- 伪元素”:after” , “:before"
伪元素就是源码html中不存在,而视觉上又存在的元素 简单用法: blockquote:before { content: open-quote; // 其他样式 } // ...
- MySTLString
auto ptr = new char[10]; delete ptr; delete 一个动态数组不能直接delete ptr, 应该是 delete[] ptr;
- GDAL显示线性shp文件
http://pan.baidu.com/s/1qWIDphU (工程文件在vs2008中编写) 1.使用到的技术 GDAL:读取矢量数据 GDI: 绘制矢量数据 2.详细解释 GDI绘图: ...