1、TCP编程的核心步骤
2、socket函数
int socket(int domain, int type, int protocol);
socket函数类似于open,用来打开一个网络连接,如果成功则返回一个网络文件描述符(int类型),之后我们操作这个网络连接都通过这个网络文件描述符。
参数详解:
dimain:
域,网络域,网络地址范围(IPV4或IPV6等),也就是协议簇;
AF_INET ip
AF_INET6 ipv6
AF_PACKET packet
PF_PACKET
PF_INET
type:
指定套接字类型:
SOCK_STREAM(TCP网络);
SOCK_DGRAM(UDP);
SOCK_SEQPACKET;
protocol:
指定协议,如果指定0,表示使用默认的协议;
IPPROTO_IP IP传输协议
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP协议
IPPROTO_SCTP SCTP传输协议
IPPROTO_ICMP ICMP协议
IPPROTO_IGMP IGMP协议
3、connect函数
对于客户端的connect() 函数,该函数的功能为客户端主动连接服务器,建立连接是通过三次握手,而这个连接的过程是由内核完成,不是这个函数完成的,这个函数的作用仅仅是通知电脑内核,让内核自动完成TCP三次握手连接,最后把连接的结果返回给这个函数的返回值。
通常的情况,客户端的connect() 函数默认会一直阻塞,直到三次握手成功或超时失败才返回(正常的情况,这个过程很快完成)。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数详解:
sockfd:
sockfd是由socket函数返回的套接字描述符。
addr:
addr是服务端地址族、服务端IP地址、服务端端口号。
addrlen:
服务端地址字节长度。
成功连接为0,失败为-1。
4、listen函数
使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。
listen函数在一般在调用bind之后,调用accept之前调用,它的函数原型是:
int listen(int sockfd, int backlog)
sockfd:
被listen函数作用的套接字,sockfd之前由socket函数返回。
在被socket函数返回的套接字fd之时,它是一个主动连接的套接字,
也就是此时系统假设用户会对这个套接字调用connect函数,
期待它主动与其它进程连接,然后在服务器编程中,
用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接。
由于系统默认时认为一个套接字是主动连接的,所以需要通过某种方式来告诉系统,
用户进程通过系统调用listen来完成这件事。
backlog:
这个参数涉及到一些网络的细节。进程处理一个一个连接请求的时候,可能还存在其它的连接请求。
因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,
使得服务器进程无法快速地完成连接请求。
如果这个情况出现了,服务器进程希望内核如何处理呢?
内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接
但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,
所以必须有一个大小的上限。
这个backlog告诉内核使用这个数值作为上限。
毫无疑问,服务器进程不能随便指定一个数值,内核有一个许可的范围。
这个范围是实现相关的。很难有某种统一,一般这个值会小30以内。
5、accept函数
accept()用来接受参数s的socket连接,它的函数原型是:
int accept(int s,struct sockaddr * addr,int * addrlen)
服务程序调用accept函数从处于监听状态的流套接字s的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回 INVALID_SOCKET。该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字的地址结构;操作系统利用第三个参数来返回新创建的套接字的地址结构的长度。
简单讲就是listen()是进入监听状态,表示愿意接收连接请求。listen之后有连接请求就将其放到队列中,accept()是把新连接请求从队列中取出,建立新的socket。注意UDP的套接子不需要listen,只有TCP的套接子监听才要listen。UDP的套接子bind需要监听的端口就可以接收数据了。
参考链接:https://blog.csdn.net/asklw/article/details/61427664
https://blog.csdn.net/liusandian/article/details/51785442
https://www.cnblogs.com/zhangshenghui/p/6095297.html