Socket编程—应用编程接口(API)
应用编程接口API:就是应用进程的控制权和操作系统的控制权进行转换的一个系统调用接口。
套接字:Berkeley UNIX操作系统定义的一种API,称为套接字接口(socket interface),简称套接字(socket)。
Socket API
最初设计:面向TCP/IP协议栈接口,目前可以面向多种协议栈。
通信模型:客户/服务器(C/S)

标识通信端点(对外):
- IP地址+端口号
操作系统/进程如何管理套接字(对内): - 套接字描述符(socket descriptor):小整数
Socket抽象
- 类似于文件的抽象
- 当应用进程创建套接字时,操作系统分配一个数据结构存储该套接字相关信息
-
返回套接字描述符
地址结构

-使用TCP/IP协议簇的网络应用程序声明端点地址(IP地址+端口号)变量时,使用结构sockaddr_in.
TCP客户端软件流程
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 连接服务器(套接字)
- 遵循应用层协议进行通信
- 关闭/释放连接
UDP客户端软件流程
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 指定服务器端点地址,构造UDP数据报
- 遵循应用层协议进行通信
- 关闭/释放套接字
--
Socket API函数
socket( ):
socket( )函数,创建套接字,成功后返回套接字描述符。

- 第一个参数(协议族):protofamily = PF_INET(TCP/IP) (利用协议族,说明面向何种协议, PF_INET说明面向TCP/IP协议族)
- 第二个参数(套接字类型):
type = SOCK_STREAM(流套接字), SOCK_DGRAM(数据报套接字) or SOCK_RAW(原始套接字,直接面向网络层,这类套接字的创建需要有特殊权限如root) (TCP/IP) - 第三个参数(协议号):0为默认协议
例:面向TCP/IP,创建一个流套接字的代码段:

socket面向TCP/IP的服务类型:

套解字架起了应用层和传输层的接口
closesocket( ):
关闭一个描述符为sd的套接字:

在windows里面是closesocket( ),在linux里面是close( ).
- 如果多个进程共享一个套接字,调用closesocket将套接字引用计数减1,减至0才关闭
- 一个进程中的多线程对一个套接字的使用无计数:如果进程中的一个线程调用closesocket将一个套接字关闭,该进程中的其他线程也将不能访问该套接字
- 返回值: 0:成功, SOCKET_ERROR: 失败
bind( ):
绑定套接字的本地端点地址:IP地址+端口号
参数:
- 套接字描述符sd
- 端点地址(localaddr):结构sockaddr_in
- 客户程序一般不必调用bind函数
- 地址通配符:INADDR_ANY
listen( ):

置服务器端的流套接字处于监听状态:
- 仅服务器端调用
- 仅用于面向连接的流套接字
设置连接请求队列大小(queuesize)
返回值: - 0:成功
- SOCKET_ERROR:失败
connect( ):

- 仅用于客户端
- 客户程序调用connect函数来使客户套接字sd与特定计算机的特定端口saddr的套接字(服务)进行连接
- 可用于TCP客户端,也可用于UDP客户端:TCP客户端:建立TCP连接, UDP客户端:指定服务器端点地址
accept( ):

- 服务程序调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道:1. 仅用于TCP套接字 2. 仅用于服务器
- 利用新创建的套接字(newsock)与客户通信
send, sendto
发送数据
recv, recvfrom
接收数据
setsockopt, getsockopt
设置套接字参数
Socket API函数小结:


网络应用的Socket API(TCP)调用基本流程
socket基本流程.png
客户端软件设计
解析服务器IP地址

解析服务器(熟知)端口号

解析协议号

TCP客户端软件流程
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 连接服务器(套接字)
- 遵循应用层协议进行通信
- 关闭/释放连接
UDP客户端软件流程
- 确定服务器IP地址与端口号
- 创建套接字
- 分配本地端点地址(IP地址+端口号)
- 指定服务器端点地址,构造UDP数据报
- 遵循应用层协议进行通信
- 关闭/释放套接字
服务器软件设计
四种类型基本服务器
- 循环无连接服务器
- 循环面向连接服务器
- 并发无连接服务器
- 并发面向连接服务器
循环无连接服务器基本流程
- 创建套接字(UDP)
- 绑定端点地址(INADDR_ANY + 端口号)
- 反复接收来自客户端的请求
- 遵循应用层协议,构造响应报文,发送给客户
数据发送
- 服务器端不能使用connect( )函数
-
无连接服务器使用sendto( )函数发送数据报
数据发送.png
获取客户端点地址
-
调用recvfrom( )函数接收数据时,自动提取
获取客户端点地址
循环面向连接服务器基本流程
循环面向连接服务器基本流程
并发无连接服务器基本流程
并发无连接服务器基本流程
并发面向连接服务器基本流程

网友评论