0%

计算机网络应用层02

Socket API

  • 使用 IP + 端口号 标识通信端点
  • 操作系统/进程使用文件描述符管理套接字 socket descriptor
  • 类似于文件的抽象
  • 当应用进程创建套接字时,操作系统分配一个数据结构存储该套接字相关信息
  • 返回套接字描述符

socket

Socket API 函数

创建socket

sd = scoket(protofamily, type, proto);

  • 创建套接字
  • 操作系统返回套接字描述符(sd)
  • 第一个参数(协议族):AF_INET (TCP/IP)
  • 第二个参数(套接字类型)
    • SOCK_STREAM TCP 流式
    • SOCK_DGRAM UDP
    • SOCK_RAW 直接面向网络层的原始套接字
  • 第三个参数(协议号):0 默认的协议

“sock_raw” 是一种特殊类型的套接字,通常用于在网络层级上进行原始数据包的读取和发送,而不经过传输层的处理。使用 sock_raw 套接字可以让程序直接访问网络层的数据,通常需要特权权限才能够操作。这种类型的套接字通常用于网络分析、数据包捕获、网络安全等领域。

socket_type

关闭套接字

int closesocket(Socket sd)

  • 关闭一个描述符为 sd 的套接字
  • 如果多个进程共享一个套接字,调用 closesocket 将套接字引用计数减 1,减至 0 才关闭
  • 一个进程中的多线程对一个套接字的使用无计数
    • 如果进程中的一个线程调用 closecocket 将一个套接字关闭,该进程中的其他线程也将不能访问该套接字

bind

绑定套接字的本地端点地址,客户端应用程序一般不需要调用 bind 函数,操作系统会帮助设置。
int bind(sd, localaddr, addrlen)

INADDR_ANY 可以绑定所有网卡的 IP 地址,来自所有网卡的请求都能接受。

listen

int listen(sd, queuesize)

  • 置服务端的流套接字处于监听状态
    • 仅服务器调用
    • 仅用于面向连接的流套接字
  • 连接队列大小

connect

connect(sd, saddr, saddrlen)

  • 客户端程序调用 connect 函数来使客户端套接字与特定计算机的特定端口的套接字进行连接
  • 仅用于客户端
  • 可用于 TCP 客户端也可以用于 UDP 客户端
    • TCP 客户端:建立 TCP 连接 调用成功说明连接成功
    • UDP 客户端:仅指定服务器端点地址(UDP 无连接),调用成功,不一定能发送消息

accept

newsock = accept(sd, caddr, caddrlen)

  • 服务程序调用 accept 函数从处于监听状态的流套接字 sd 的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道
    • 仅用于 TCP 套接字
    • 仅用于服务器
  • 利用新创建的套接字与客户通信 (点对点)

send sendto

send(sd, *buf, len, flags)
sendto(sd, *buf, len, flags, destaddr, addrlen)

  • send 函数用于 TCP 套接字(客户与服务器)或调用了 connect 函数的 UDP 客户端套接字
  • sendto 函数用于 UDP 服务器端套接字与未调用 connect 函数的 UDP 客户端套接字

recv recvfrom

recv(sd, *buf, len, flags)
recvfrom(sd, *buf, len, flags, sendraddr, saddrlen)

  • recv 函数从 TCP 连接的另一端接收数据,或者从调用了 connect 函数的 UDP 客户端套接字接收服务器来的数据
  • recvfrom 函数用于从 UDP 服务器端套接字与未调用 connect 函数的 UDP 客户端套接字接收对端数据

setsockopt getsockopt

网络字节序列

  • TCP/IP 定义了标准的用于协议头中的二进制整数表示:网络字节序(network byte order)
  • 某些 Socket API 函数的参数需要存储网络字节序(IP,端口)
    • htons:本地字节序转为网络字节序(16bits)
    • ntohs: 网络字节序转为本地字节序(16bits)
    • htonl:本地字节序转为网络字节序(32bits)
    • ntohl:网络字节序转为本地字节序(32bits)

解析服务器 IP 地址

客户端可能使用域名或 IP 地址标识服务器,而 IP 协议需要用 32 位二进制 IP 地址,需要将域名或 IP 地址转为 32 位 IP 地址。

inet_addr

实现点分十进制 IP 地址到 32 位 IP 地址转化

gethostbyname

实现域名到 32 位 IP 地址转换

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

客户端还可能使用服务名(HTTP)标识服务器端口,需要将服务名转换为熟知端口。

getservbyname

解析协议号

协议名到协议号的转换

getprotobyname