基本TCP套接字编程

基本TCP套接字编程

概述

基本TCP客户/服务器程序的套接字函数
这里写图片描述

socket函数

    #include <sys/socket.h>
    int socket(int family, int type, int protocol)
    返回:若成功则为非负描述符,若则为-1

其中 family 参数指明协议族,为某个常值。该参数也往往称为协议域。

family说明
AF_INETIPv4协议
AF_INET6IPv6协议
AF_LOCALUNIX域协议
AF_ROUTE路由套接字
AF_KEY密钥套接字

  
其中 type 指明套接字的类型,它也是某个常值。

type说明
SOCK_STREAM字节流套接字
SOCK_DGRAM数据包套接字
SOCk_SEQPACKET有序分组套接字
SOCK_RAM原始套接字

  
protocol 参数为某个协议的类型常值,或者设为0,以选择所给定的 familytype 的系统默认值。并非所有的组合都是有效。有效组合见下图。

protocol说明
IPPROTO_TCPTCP传输协议
TPPROTO_UDPUDP传输协议
IPPROTO_SCTPSCTP传输协议


socket函数中family和type参数的组合
这里写图片描述

connect 函数

TCP客户用connect函数建立与TCP服务器的连接。

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);
返回: 若成功返回则为0,若出错则为-1.

如果是TCP套接字,调用 connect 函数 将激发 TCP 的 三次握手,而且仅在链接建立成功或者出错时放回,错误返回可能有一下几种情况。
1. 若tcp客户没有收到SYN响应,则会返回ETIMEDOUT错误
2. 若对客户的SYN的响应是RST(表示复位),则表明该服务器主机在我们指定的端口上没有进程再等待与之连接。这是一种硬错误,客户一接受到,就马上返回SCONNREFUSED错误
3. 若客户发出的SYN在中间的某个路由引发了一个目的不可达的ICMP错误,则认为是一种软错误。客户端会进行重发,一段时间后还是没有收到相应,则会把保存的消息(ICMP错误)作为EHOSTUNREACH或ENETUNREACH错误放回给进程。

bind函数

bind 函数把一个本地协议地址付给一个套接字。对于网际网协议,协议地址是32位的IPv4地址或者128的IPv6地址与16位的tcp或者udp端口号的组合。

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
返回:成功返回0,若出错则为-1

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

listen 函数

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

#include <sys/socket.h>
int listen(int sockfd, int backlog)
返回: 若成功返回0,若出错则为-1

listen 函数仅有tcp服务器调用,它做两件事情。
1. 当socket 函数创建一个套接字时,它被假设为一个主动套接字,也就是说,它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应接受指向该套接字的连接请求。
2. 本函数的第二参数规定了内核应该为相应的套接字排队的最大连接个数。

为理解其中的backlog参数,我们必须认识到内核为任何一个给定的监听套接字维护两个队列
1. 未完成连接队列,每个这样的syn 分节对应其中一项:已由某个客户发出并到达服务器,而服务器正在等待相应的tcp三次握手过程。这些套接字处于SYN_RCVD状态。
2. 已完成连接队列,每个已经完成TCP三路握手的客户对应其中一项。这些套接字处于ESTABLISHED状态
这里写图片描述

accept 函数

accept 函数由TCP服务器调用,用于从已完成连接队列对头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠(假定套接字为默认的阻塞方式)

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
返回:若成功则为非负描述符,若出错则为-1

参数cliaddr和addrlen用来返回已连接的对端进程(客户)的协议地址。addrlen是值-结果参数。调用前,我们将有*addrlen所引用的整数数值设置为有cliaddr所指的套接字地址接受的长度,返回时,该整数值即为由内核存放在该套接字地址结构内的确切字节数。

如果accept成功,那么返回值由内核自动生成一个全新的描述符,代表与所返回客户的tcp连接。我们称accept的第一个参数为监听套接字。称它返回的套接字为已连接套接字。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接受的客户连接创建一个已连接套接字。当服务器完成对某个给定客户的服务时,相应的已连接套接字就被关闭了。

forkexec 函数

fork 函数是unix中派生新进程的唯一方法

#include <unistd.h>
pid_t fork(void)
返回:在子进程为0,在父进程中为子进程ID,若出错则为-1

close 函数

通常的 unix close 函数也用来关闭套接字,并终止TCP连接

#include <unistd.h>
int close(int sockfd)
返回:成功0,出错-1
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值