【UNIX网络编程(二)】基本TCP套接字编程函数

基于TCP客户/服务器程序的套接字函数图如下:

执行网络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函数来建立与TCP服务器的链接。

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);  /*返回:若成功则为0,若出错则为-1*/

sockfd是由socket函数返回的套接字描述符,第二个、第三个参数分别是一个指向套接字地址结构的指针和该结构的大小。客户在调用函数connect前不必非得调用bind函数,因为如果需要的话,内核会确定源IP地址,并选择一个临时端口号作为源端口。如果是TCP套接字,调用connect函数将激发TCP的三路握手过程,而且仅在连接建立成功或出错时才返回,其中出错返回可能有以下几种情况:

a、若TCP客户没有收到SYN分节的响应,则返回ETIMEDOUT错误。

b、若对客户的SYN的响应是RST(表示复位),则表明该服务器主机在我们指定的端口上没有进程在等待与之连接。

c、若客户发出的SYN在中间的某个路由器上引发了一个“destination unreachable”ICMP错误,则认为是一个软错误。

bind函数把一个本地协议地址赋予一个套接字。对于网际网协议,协议地址是32位的IPv4地址与16位的TCP或UDP端口号的组合。

#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);/*返回,成功则为0,出错则为-1*/

第二个参数是一个指向特定于协议的地址结构的指针,第三个参数是该地址结构的长度,对于TCP,调用bind函数可以指定一个端口号,或指定一个IP地址,也可以两者都指定,还可以都不指定。

服务器在启动时捆绑它们的众所周知端口。如果一个TCP客户或服务器未曾调用bind捆绑一个端口,当调用connect或listen时,内核就要为相应的套接字选择一个临时端口号。让内核选择临时端口对于TCP客户来说是正常的,除非应用需要一个预留端口;而毁于TCP服务器来说却极为罕见,因为服务器是通过他们的众所周知端口被大家认识的。

进程可以把一个特定的IP地址捆绑到它的套接字上,不过这个IP地址必须属于其所在主机的网络接口之一。

如果指定端口号为0,那么内核就bind被调用时选择一个临时端口。然而如果指定IP地址为通配地址,那么内核将等到套接字已连接TCP或已在套接字上发出数据报时才选择一个IP地址。对于IPv4来说,通配地址由常量INADDR_ANY来指定,其值为0。

注意:如果让内核来为套接字选择一个临时端口号,那么必须注意,函数bind并不返回所选择的值。实际上,由于bind函数的第二个参数有const限定词,它无法返回所选之值。为了得到内核所选择的这个临时端口值,必须调用函数getsockanme来返回协议地址。

listen函数仅由TCP服务器调用,它做两件事:

1、当socket函数创建一个套接字时,它被假设为一个主动套接字,也就是说,它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应该受指向该套接字的连接请求。

2、本函数的第二个参数规定了内核应该为相应套接字排队的最大连接个数。

#include <sys/socket.h>

int listen(int sockfd, int backlog);/*返回:若成功则为0,出错则为-1*/

本函数通常应该在调用socket和bind这两个函数之后,并在调用accept函数之前调用。

为理解backlog参数,必须认识到内核为任何一个给定的监听套接字维护两个队列:

1、未完成连接队列,每个这样的SYN分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待完成相应的TCP三路握手过程,这些套接字处于SYN_RCVD状态

2、已完成连接队列,每个已完成TCP三路握手过程的客户对应其中一项。这些套接字处于ESTBLISHED状态。

accept函数由TCP服务器调用,用于从已完成连接队列返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);   /*返回:若成功则为负描述符,若出错则为-1*/

参数cliaddr和addrlen用来返回已连接的对端进程协议地址。如果accept成功,那么其返回值是由内核自动生成的一个全新描述符,代表与所返回客户的TCP链接。在讨论accept函数时,称第一个参数为监听套接字描述符,称返回值为已连接套接字描述符。区分这两个套接字非常重要。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字。当服务器完成对某个给定客户的服务时,相应的一两节套接字就被关闭。

本函数最多返回3个值:一个既可能是新套接字描述符也可能是出错只是的整数、客户进程的协议地址以及该地址的大小。如果对返回客户协议地址不感兴趣,可以把cliaddr和addrlen均置为空指针。

close函数用来关闭套接字,并终止TCP连接。int close(int sockfd);返回:成功则为0,出错则为-1。

【UNIX网络编程(二)】基本TCP套接字编程函数,布布扣,bubuko.com

时间: 2024-12-21 22:26:25

【UNIX网络编程(二)】基本TCP套接字编程函数的相关文章

Unix网络编程之基本TCP套接字编程(上)

TCP客户/服务器实例 服务器程序 #include "unp.h" int main(int argc, char **argv) { int listenfd, connfd; pid_t childpid; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; listenfd = Socket(AF_INET, SOCK_STREAM, 0); //1 bzero(&servaddr, sizeof(servad

《网络编程》基于 TCP 套接字编程的分析

本节围绕着基于 TCP 套接字编程实现的客户端和服务器进行分析,首先给出一个简单的客户端和服务器模式的基于 TCP 套接字的编程实现,然后针对实现过程中所出现的问题逐步解决.有关基于 TCP 套接字的编程过程可参考文章<基本 TCP 套接字编程>.该编程实现的功能如下: (1)客户端从标准输入读取文本,并发送给服务器: (2)服务器从网络输入读取该文本,并回射给客户端: (3)客户端从网络读取由服务器回射的文本,并通过标准输出回显到终端: 简单实现流图如下:注:画图过程通信双方是单独的箭头,只

《网络编程》基本 TCP 套接字编程

在进行套接字编程之前必须熟悉其地址结构,有关套接字的地址结构可参考文章<套接字编程简介>.基于 TCP 的套接字编程的所有客户端和服务器端都是从调用socket 开始,它返回一个套接字描述符.客户端随后调用connect 函数,服务器端则调用 bind.listen 和accept 函数.套接字通常使用标准的close 函数关闭,但是也可以使用 shutdown 函数关闭套接字.下面针对套接字编程实现过程中所调用的函数进程分析.以下是基于 TCP 套接字编程的流程图: socket 函数 套接

【UNIX网络编程(四)】TCP套接字编程详细分析

引言: 套接字编程其实跟进程间通信有一定的相似性,可能也正因为此,stevens这位大神才会将套接字编程与进程间的通信都归为"网络编程",并分别写成了两本书<UNP1><UNP2>.TCP套接字编程是套接字编程中非常重要的一种,仔细分析,其实它的原理并不复杂.现在就以一个例子来详细分析TCP套接字编程. 一.示例要求: 本节中试着编写一个完成的TCP客户/服务器程序示例,并对它进行深入的探讨.该示例会用到绝大多数的基本函数,未用到但比较重要的函数会在后面的补充上

UNIX网络编程笔记(3)—基本TCP套接字编程

基本TCP套接字编程 主要介绍一个完整的TCP客户/服务器程序需要的基本套接字函数. 1.概述 在整个TCP客户/服务程序中,用到的函数就那么几个,其整体框图如下: 2.socket函数 为了执行网络I/O,一个进程必须要做的事情就是调用socket函数.其函数声明如下: #include <sys/socket.h> int socket(int family ,int type, int protocol); 其中: family:指定协议族 type:指定套接字类型 protocol:指

unix网络编程第四章----基于TCP套接字编程

为了执行网络I/O操作.进程必须做的第一件事情就是调用Socket函数.指定期待的通信协议 #include<sys/socket.h> int socket(int family,int type,int protocol); family表示协议族,比如AF_INET,type表示套接字类型, protocol一般设置为0 family: AF_INET ipv4协议 type: SOCK_STREAM 字节流套接字 SOCK_DGRAM 数据报套接字 SOCK_RAW 原始套接字 pro

Unix网络编程学习笔记之第4章 基于TCP套接字编程

1. socket函数 int socket(int family, int type,int protocol) 成返回一个套接字描述符.错误返回-1 其中family指定协议族,一般IPv4为AF_INET, IPv6为AF_INET6. 其中type指定套接字类型,字节流:SOCK_STREAM.   数据报:SOCK_DGRAM. 一般情况下通过family和type的组合都可以唯一确定一个套接字类型.所以一般我们就把protocol设为0就可以了. 有时在某些特殊情况下,family和

《网络编程》基本 UDP 套接字编程

在前面文章中介绍了<UDP 协议>和<套接字数据传输>.UDP 协议和 TCP 协议不同,它是一种面向无连接.不可靠的传输层协议.在基于 UDP 套接字编程中,数据传输可用函数 sendto 和 recvfrom.以下是基本 UDP 套接字编程过程: sendto 与 recvfrom 函数 这两个函数的功能类似于 write 和 read 函数,可用无连接的套接字编程.其定义如下: /* 函数功能:发送数据: * 返回值:若成功则返回已发送的字节数,若出错则返回-1: * 函数原

套接字编程相关函数(2:TCP套接字编程相关函数)

1. 基本TCP客户/服务器程序的套接字函数 2. socket函数 为了执行网络I/O,一个进程必须做的第一件事就是调用socket函数,指定期望的通信协议类型.其定义如下: #include <sys/socket.h> int socket(int family, int type, int protocol); // 返回:若成功则返回非负描述符,若失败则返回-1 其中:family参数指明协议族,它是图4-2中所示的某个常值.该参数也往往被称为协议域. type指明套接字类型,它是图