网络应用的Socket API编程的基本调用流程

哈喽!我是善水,本文章来自于本人在哈工大计算机网路之网尽其用系列课程学习之后的理解所写:
在计算机OSI七层协议的顶层-应用层的网络应用中,Socket套接字编程使我们必须使用的技术,现在就记录一下套接字的网络编程的客户端服务器的调用流程;如下为基本流程图:

网络应用的Socket API编程的基本调用流程_第1张图片
一、服务端
1.首先我们知道在客户端和服务器之间我们必须先开启服务器进程,以此来等待客户端的连接,所以我们先来看一下服务器的初始化流程:
1.1服务器调用WSAStartup()函数,来初始化套接字进程;

int WSAStartup(WORD wVersionrequest,LPWSADATA IpWSADATA)
#参数:第一个参数:为指明程序调用的winsocket版本,为十六进制,高字节表示副版本,低字节表示低版本

1.2紧接着调用socket()函数来创建一个全局的套接字对象,并返回对象句柄s;

s = socket(protofamily,type,family)
#创建套接字并返回句柄s
#参数,Protofamily:为协议族;Protofamily = PF_INET(TCP/IP)
#     type:套接字类型;取值为SOCKET_STREAM、SOCKET_DRRAM、SOCKET_RAW
#     family(协议号,默认为0)

网络应用的Socket API编程的基本调用流程_第2张图片

1.3在创建 全局套接字s后,我们需要在服务器上绑定来自不同客户端的ip地址和端口号,(这里采用的bind()为INADDR_ANY也就是地址通配符的动态绑定机制绑定不同的地址)

int bind(sd, localaddr,addrlen)
#绑定套接字的本地端口地址(ip地址+端口号)
#参数:sd为套接字描述符;localaddr(端点地址)

1.4在绑定之后,服务器就只要处于监听状态了,来监听来自客户端的请求等:

int listen(sd,squeuesize)
#参数sd为套接字描述符
#参数squeuesize设置信息队列大小
#返回值:0表示成功,SOCKET_ERROR表示失败
#listen函数仅仅面向连接的流套接字(tcp);只有服务器才需要监听函数

1.5 accept函数,服务程序调用 ns = accept()函数来从监听状态的流套接字中取出队列的第一个元素的客户端请求,并且创建一个新的套接字ns来与客户端套接字创建连接通道。

1.6 通过accept函数的新建套接字ns,服务器与客户端套接字建立连接,通过套接字之间的通信,服务器端调用recv()来接受客户端数据。此函数只适用TCP连接或者连接模式的UDP连接(也就是通过connect()连接的udp连接)。
1.7 基于对recv()函数的收到请求,服务器端调用send(ns)返回给程序客户端信息。
1.8 如果基于套接字的客户端与服务器的通信完成之后,则调用closeSocket(ns)来关闭 当前的套接字。之后服务器端又恢复到listen的状态循环以上的accpet函数到closesocket()之间的步骤。如果套接字关闭不再使用,则关闭WSACleanup()来释放资源

总结服务器端的主要步骤:

网络应用的Socket API编程的基本调用流程_第3张图片

二、客户端
在服务器端完成了accept()步骤之后,我们的客户端就可以进行连接了。以下为类似的具体过程
2.1 同样是初始化WSAStartup()来初始化socket库
2.2 紧接着调用socket()函数来创建一个全局的套接字对象,并返回对象句柄s;

s = socket(protofamily,type,family)

2.3 在创建本地套接字之后我们就可以调用connect向服务器端发送连接请求。
2.4 在服务端收到连接请求之后,会发送连接确认到客户端,客户端收到连接确认之后,就调用套接字的send()函数发送流数据到服务器端。
2.5 在这之后客户端收到来自于服务器的信息之后,调用recv(s)函数来接受服务器发送的信息
2.6 在这个套接字完成通信之后,就可以关闭当前的套接字。最后基于对服务器的通信完成之后销毁套接字对象,释放资源(WSACleanUp)

注意:在上面的通信过程中,connect()和accept()还有recv()函数都是会出现拥塞情况。可以考虑多并发的使用。
于2017 12 9 18:40

你可能感兴趣的:(网络笔记)