【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。





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5225231.html,如需转载请自行联系原作者

相关文章
|
网络协议 安全 网络安全
网络编程:基于socket的TCP/IP通信。
网络编程:基于socket的TCP/IP通信。
|
Unix Shell API
组合思维:Unix 哲学到底给现代编程带来哪些重要启示?
Unix哲学提供了一套简洁而强大的设计理念,这些理念在现代编程中依然具有重要的指导意义。通过模块化设计、组合工具、避免过早优化以及注重可复用性和可扩展性,开发者可以构建出更高效、更健壮的软件系统。希望本文能够帮助读者深入理解Unix哲学,并在实际开发中应用这些宝贵的设计原则。
521 25
|
监控 安全
公司上网监控:Mercury 在网络监控高级逻辑编程中的应用
在数字化办公环境中,公司对员工上网行为的监控至关重要。Mercury 作为一种强大的编程工具,展示了在公司上网监控领域的独特优势。本文介绍了使用 Mercury 实现网络连接监听、数据解析和日志记录的功能,帮助公司确保信息安全和工作效率。
376 51
|
机器学习/深度学习 API Python
Python 高级编程与实战:深入理解网络编程与异步IO
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧、数据科学、机器学习、Web 开发和 API 设计。本文将深入探讨 Python 在网络编程和异步IO中的应用,并通过实战项目帮助你掌握这些技术。
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
736 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
440 13
|
Web App开发 缓存 网络协议
不为人知的网络编程(十八):UDP比TCP高效?还真不一定!
熟悉网络编程的(尤其搞实时音视频聊天技术的)同学们都有个约定俗成的主观论调,一提起UDP和TCP,马上想到的是UDP没有TCP可靠,但UDP肯定比TCP高效。说到UDP比TCP高效,理由是什么呢?事实真是这样吗?跟着本文咱们一探究竟!
1071 10
|
数据库连接 Go 数据库
Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性
本文探讨了Go语言中的错误注入与防御编程。错误注入通过模拟网络故障、数据库错误等,测试系统稳定性;防御编程则强调在编码时考虑各种错误情况,确保程序健壮性。文章详细介绍了这两种技术在Go语言中的实现方法及其重要性,旨在提升软件质量和可靠性。
333 1
|
算法 Unix 数据安全/隐私保护
Python编程--UNIX口令破解机
Python编程--UNIX口令破解机
316 1
|
网络协议 Java
谈谈TCP/IP网络编程
【9月更文挑战第1天】在当今数字化的世界中,网络通信是连接各种设备和系统的关键。TCP/IP协议作为互联网通信的基石,被广泛应用于各种网络场景。了解TCP/IP网络编程的概念,并掌握如何在Java中实现TCP/IP通讯,对于开发人员来说是非常重要的。
250 4