计算机网络笔记(四):Socket编程

本文详细介绍了套接字API在Windows Socket(WinSock)中的应用,包括WSAStartup、socket、bind、listen、accept、connect等关键函数的使用。此外,还讲解了网络字节顺序的概念及其转换函数,以及如何解析服务器的IP地址、端口号和协议号。最后,概述了TCP/UDP客户端软件流程和服务器软件设计的基本模式。
摘要由CSDN通过智能技术生成

前言

在这里插入图片描述
在这里插入图片描述
几种典型的应用编程接口

  • Berkeley UNIX操作系统定义了一种API,称为套接字接口(socket interface),简称套接字Socket
  • 微软公司在其操作系统中采用了套接字API,形成了一个稍有不同的API,并称之为Windows Socket Interface,WinSock
  • AT&T为其UNIX系统V定义了一种API,简写为TLI(Transport Layer Interface)

Socket API

  • 最初设计:面向BSD Unix-Berkeley,面向TCP/IP协议栈接口
  • 目前:事实上的工业标准,绝大多数操作系统支持
  • Internet网络应用最典型的API接口
  • 通信模型:客户/服务器(C/S)
  • 应用进程间通信的抽象机制
  • 标识通信端点(对外):IP地址+端口号
  • 操作系统/进程如何管理套接字(对内)?套接字描述符(Socket descriptor):进程创建套接字时的返回值

Socket 抽象

  • 类似文件的抽象
  • 当应用进程创建套接字时,操作系统分配一个数据结构存储该套接字相关信息
  • 返回套接字描述符

在这里插入图片描述

struct sockaddr_in {
	u_char sin_len;	// 地址长度
	u_char sin_family;	// 地址族
	u_short sin_port;	// 端口号
	struct in_addr sin_addr;	// IP地址
	char sin_zero[8];	// 保留位,置0
}

Socket API 函数(WinSock为例)

WSAStartup 函数

使用Socket的应用程序在使用Socket之前必须首先调用WSAStartup函数

int WSAStartup(WORD wVersionRequested,LPWSADATA IpWSAData);

两个参数:

  1. 第一个参数指明程序请求使用的WinSock版本,其中高位字节指明副版本、低位字节指明主版本。
    • 十六进制整数,例如0x102表示2.1版
  2. 第二个参数返回实际的WinSock的版本信息
    • 指向WSADATA结构的指针

例:使用2.1版本的WinSock的程序代码段

wVersionRequested = MAKEWORD(2, 1);
err = WSAStartup(wVersionRequested, &wsaDara);

WSACleanup 函数

应用程序在完成对请求的Socket库的使用,最后要调用WSACleanup函数,解除与Socket库的绑定,释放Socket库所占用的系统资源。

int WSACleanup(void)

Socket 函数

创建套接字,操作系统返回套接字描述符(sd)

sd = socket(protofamily, type, proto);
  1. 第一个参数(协议族):对于TCP/IP协议族,protofamily = PF_INET(TCP/IP)
  2. 第二个参数(套接字类型)
  3. 第三个参数(协议号):0为默认

在这里插入图片描述
CloseSocket 函数

关闭一个描述符为sd的套接字,如果多个进程共享一个套接字,调用closesocket将套接字引用计数减1,减至0才关闭。

int closesocket(SOCKET sd);

一个进程中的多线程对一个套接字的使用无计数:如果进程中的一个现场调用closesocket将一个套接字关闭,该进程中的其他线程也将不能访问该套接字。

Bind 函数

绑定套接字的本地端点地址:IP地址+端口号

int bind(sd, localaddr, addrlen);
  • 套接字描述符(sd)
  • 端点地址
  • 客户程序一般不必主动调用bind函数,操作系统将自动调用。
    在这里插入图片描述

Listen 函数

置服务器端的流套接字处于监听状态。

  • 仅服务器端调用
  • 仅用于面向连接的流套接字
  • 设置连接请求队列大小(queuesize)
int listen(sd, queuesize);

connect 函数

客户端程序调用connect函数来使客户套接字(sd)与特定计算机的特定端口(saddr)的套接字(服务)进行连接。其仅用于客户端。

int connect(sd, saddr, saddrlen);

accept 函数

服务端调用accept函数从处于监听状态的流套接字sd的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户端套接字创建连接通道。

  • 仅用于TCP套接字
  • 仅用于服务器
newsock = accept(sd, caddr, caddrlen);

利用新创建的套接字(newsock)与客户通信,保证服务器可以并发。

send、sendto 函数

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

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

recv、recvfrom 函数

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

recv(sd, *buffer, len, flags);
recvfrom(sd, *buf, len, flags, sendaddr, saddrlen);

setsockopt、getsockopt 函数

setsockopt() 函数用来设备套接字sd的选项参数
getsocket()函数用于获取任意类型、任意状态套接口的选项当前值,并把结果存入optval。

int setsocketopt(int sd, int level, int optname, *optval, int optlen);
int getsocketopt(int sd, int level, int optname, *optval, socklen_t optlen);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据解析

网络字节顺序

TCP/IP 定义了标准的用于协议头中的二进制整数表示:网络字节顺序(network byte order)。

某些Socket API函数的参数需要存储为网络字节顺序(如IP地址、端口号等)。这时候需要实现本地字节顺序与网络字节顺序转换的函数:

  • htons:本地字节顺序 -> 网络字节顺序(16bits)
  • ntohs:网络字节顺序 -> 本地字节顺序(16bits)
  • htonl:本地字节顺序 -> 网络字节顺序(32bits)
  • ntohl:网络字节顺序 -> 本地字节顺序(32bits)

解析服务器IP地址、端口号

客户端可能使用域名(如:study.163.com)或 IP地址(如:123.58.180.121)表示服务器。IP协议需要使用32位二进制IP地址。

需要将域名或IP地址转换为32位IP地址。

  • 函数inet_addr()实现点分十进制IP地址到32位IP地址转换
  • 函数gethostbyname()实现域名到32位IP地址转换:返回一个指向结构hostent的指针

客户端还可能使用服务名(如HTTP)表示服务器端口。

需要将服务名转换为熟知的端口号。

  • 函数getservbyname():返回一个指向结构servent的指针

解析协议号

客户端可能使用协议名(如:TCP)指定协议,需要将协议名转换为协议号(如:6)。

  • 函数getprotobyname()实现协议名到协议号的转换:返回一个指向结构protoent的指针

TCP/UDP客户端软件流程

TCP:

  1. 确定服务器IP地址与端口号
  2. 创建套接字
  3. 系统自动分配本地端点地址(IP+端口号)
  4. 连接服务器(套接字)
  5. 遵循应用层协议进行通信
  6. 关闭/释放连接

UDP:

  1. 确定服务器IP地址与端口号
  2. 创建套接字
  3. 系统自动分配本地端点地址(IP+端口号)
  4. 指定服务器端点地址,构造UDP数据报
  5. 遵循应用层协议进行通信
  6. 关闭/释放套接字

服务器软件设计

四种类类型基本服务器

  • 循环无连接服务器(iterative connectionless)
  • 循环面向连接服务器(iterative connection-oriented)
  • 并发无连接服务器(concurrent connectionless)
  • 并发面向连接服务器(concurrent connection-oriented)

循环无连接服务器(iterative connectionless): 一次只处理一个客户的服务请求,直到这个服务请求处理完毕。

在这里插入图片描述
循环面向连接服务器(iterative connection-oriented)
在这里插入图片描述
并发无连接服务器(concurrent connectionless)

在这里插入图片描述

并发面向连接服务器(concurrent connection-oriented)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值