TCP/IP协议学习笔记(三)Window下socket编程(一)

      最后更新:2022-04-11 00:17

      视觉工作室现在支持插座通信。

      DLL的加载

      编译后, 使用 # pragma 命令装入 :
      #pragma 批注( lib, “ ws2_ 32. / 加载 ws2_ 32. dll )

      WSAStartartup () 方法也必须先初始化,然后才能使用 DLL 来提供 WinSock 规格版本,其原型为:

      通过MAKEWORD函数来设置版本好

      WSAData组织

      获取版本编号和配置数据

      ws2_32应纳入项目。

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

      常见问题

      1. 使用inet_pton () 或 InetPton () 代替,或使用 _ WINSOCK_DEPREGED_NO_WARININGS 来禁用已折旧的 API 。
        解决方法在这里插入图片描述
      2. 未定义类型名称“ ockaddr_ in” 显示为未定义更改类型
        原因有两个,第一是没有增加 Ws2_32 。 我道歉, 但我不知道我在说什么。它可以手工添加到项目的链接设置中。第二个问题是头条标题只指定结构的名称。但是,没有别名可以形容。因此,不能利用袜子装配直接申报该类型。这是该国历史上第一次使用“struckt sockaddr_in”一词来定义它。您也可以在键入 dedef 区块 sockaddr_ in 时添加别名声明来运行 。

      套接字socket

      SOCKET socket(int af, int type, int protocol);

      1. 这是一个地址家庭,如果它是 地址个人。这是 IP 地址格式 。AF_INET和AF_INET6的使用最为广泛。A. F. 是缩略版的"联络家庭"INET是“Innetnet”的缩写。IPv4 地址使用 AF_INET 。
      2. 类型是一种数据传输方法,通常由SOCK_STREAM和SOCK_DGRAM使用,SOCKE_STREAM指定流生成合成和SOCK_DGRAM生成数据报告。
      3. 议定书是转让议定书,通常被IPPROTO_TCP和IPPTTO_UDP分别作为TCP和UDP转让议定书使用的。
      4. 成功时返回一个很小的非负整数,与文档描述符相同,我们使用套接字描述符,即袜子。INVALID_SOCKET可以被指为( C)WSAGetLastError寻找具体的问题代码。

      SONKET一词的定义是:typedef UINT_PTR SOCKET;
      UINT_PTR为unsigned long long。

      在这两种情况下,只有一项协议符合协议价值可改为0的标准,而该系统将自动推动哪些协议应用于履约。

      捆绑 () 和连接 () 的方法

      Socket () 方法用于构建合成、 确定属性, 然后服务器被绑定功能绑定到某个 IP 地址和端口, 以便通过 IP 地址和端口运行的数据可以给与合成 。
      客户端必须使用连接() 方法来建立连接 。

      bind() 函数

      int bind(SOCKET sock, const struct sockaddr *addr, int addrlen);

      1. Sock 是套接字文件描述符的缩写 。
      2. Addr 是 sockaddr 结构变量的指针 。
      3. 使用大小 () 确定 eldr 变量, 以决定 adrlen 的大小 。
      4. 返回值:成功则返回0 ,否则,它将返回SOCKET_ERROR,并且可以通过调用WSAGetLastError来寻找具体的问题代码。

      Sockaddr_ in 结构

      以_addr 内的结构

      将新生成的套接字嵌入到 IP 地址和端口 1234 :

      还正式登记了1024至49151个港口号码,这些港口号码可用于任何通信目的。
      由于传输数据需要在网络序列中发送数据,必须命名。inet_addr和htons

      函数连接()

      int connect(SOCKET sock, const struct sockaddr *serv_addr, int addrlen);
      这些论点的描述方式与约束()相同。
      如果连接成功, 返回 0, 则生成 SOCKET_ ERROR 错误 。

      倾听()和接受()的方法

      约束软件包的约束()的使用需要应用程序()方法,使软件包能够输入被动监听模式,并随时使用接受()功能回应客户对服务器终端应用程序的请求。

      函数听众()

      int listen(SOCKET sock, int backlog);

      1. 听声状态袜套接字
      2. 积压是所需队列的最大长度。
        此参数通常被填充为SOMAXCONN允许算法自动为您选择最佳数字 。
      3. 成功时返回 0, 否则返回 SOCKET_ Error 。

      虽然没有客户请求,但该带处于“睡觉”状态,只有在收到客户请求时,该带才“醒悟”。

      Nota bene: 听 () 只让带子监听, 不接收请求。 要接收请求, 需要接受( ) 的方法 。

      功能已接受()

      当套接字处于监听状态时,可以通过 功能已接受()来接收客户端请求。
      SOCKET accept(SOCKET sock, struct sockaddr *addr, int *addrlen);

      它有与听者() 和连接() 相同的参数: 袜子是一个服务器终端链接, 并且Addr 是 sockaddr_ in 结构中的一个变量 。参数添加器的长度由 adrrlen 给出 。可通过调用()大小获得。

      接受 () 生成与客户端互动的新设置单词, addr 保留客户端的 IP 地址和端口号, 袜子是服务器的设置单词 。
      与后端和客户端连接时, 使用此新生产的 Socket 而不是旧服务器端的 Socket 。

      接受() 在收到新的请求之前将停止程序执行( 终端代码无法运行 ) 。

      Socket 数据传输和接收

      用发送()函数传输数据,其原型为:
      int send(SOCKET sock, const char *buf, int len, int flags);

      1. 软件包发送数据时的嵌套
      2. Buff 是数据传输缓冲的地址 。
      3. 列载要传输的字节数,
      4. 标记是传输数据的选项。 通常设置为零 。
        其他: MSG_OOB: 传输含有额外特殊数据但通常不建议使用但通常被忽略的数据部分; MSG_DONTROUTE: 指定的数据不应像 Windows 软件包服务所提供的那样,通过路径受到限制。 应用程序可以选择忽略此信件 。
      5. 返回已成功写入的字节数量, 但未返回 SOCKET_ ERROR: 函数接收相关的错误代码并相应处理 。

      发送() 不立即将数据发送到网络 。而是把数据带进缓冲地带 但只是把数据带进缓冲地带缓冲区的数据随后通过TCP协议发送给目的地计算机。当数据首次写入缓冲区时,数据首次写入缓冲区。函数可以正确返回。无论他们是否达到目标机器,我不介意他们是否在互联网上公布TCP负责所有这些事情。

      数据是通过矩形函数接收的,其原型为:
      int recv(SOCKET sock, char *buf, int len, int flags);

      1. (a) 第一个参数为收件人终端集提供字词说明;
      2. 第二个选项指定一个缓冲区,用于储存由矩流函数返回的数据。
      3. 第三个参数表示 buff 的长度。
      4. 在大多数情况下,第四个参数为零。
      5. 成功时, 收到的字符数会返回, 失败时会返回 SOCKET_ ERROR 。

      mouthockopt () 方法返回输入输出缓冲的默认大小, 通常为 8K :

      阻塞模式

      在通过 TCP 套接字传输数据时( 默认) 使用以下语法 :

      1. 首先会检查缓冲区,如果缓冲区可用空间的面积少于交付数据的数量,因此,将防止(暂停)书面/发送()职能。一旦缓冲区内的所有数据都传送到目的地机器上腾出足够的空间,只有写 () / 转发 () 函数唤醒并继续写入数据 。

      2. 当 TCP 协议将数据发送到网络时, 输出缓冲将被锁定, 不允许写入, 并停止写入( )/ send (), 直到数据被发送并解锁, 并且写( )/ send () 不醒过来 。

      3. 如果数据必须写得长度大于缓冲区最长长度,则必须写出批次。

      4. 在将所有数据写入缓冲区之前,不可能返回。

      当使用 recrov () 读取数据时 :

      1. 将首先检查缓冲区,如果在缓冲区发现数据,功能将停止,直到在网络上找到数据并放置到缓冲区。

      2. 如果用比缓冲区内数据短的长度阅读数据,缓冲区内的所有数据不能同时读出,其余数据将累积到再读取正弦()函数时为止。

      3. 校正v() 方法直到所有数据都读完后才返回;否则,它就会停滞。

      注意到TCP标签和数据无边无际。

      断开连接

      默认情况下,如果您不想加入,您将立即将FIN软件包传送到网络。如果缓冲区内还有任何数据,毫无疑问。然后关闭 () 将在输出缓冲区数据传输完成后交付 FIN 软件包 。也就意味着,如果使用关闭()/关闭(closesocket)(),缓冲区的数据输出就会丢失。不要使用关闭 () 。

      int shutdown(SOCKET s, int howto);
      在 Windows 中, Howto 的数值如下:

      • SD_REMEVE: 此函数终止接收操作, 即输入流断开 。
      • SD_SEND: 此函数终止传输操作, 即输出流断开 。
      • 同时关闭接收和发送进程 。

      确切地说,要关闭插座, 请使用 Clessocket () 。此函数从内存中删除套接字描述符( 或控件) 。此后再也不能使用这一工具了。申请关闭插座后这条线的连接和缓存同样失去了意义。TCP 协议启动自动终止连接的行动 。

      关闭 () 用于结束连接, 而不是绑绑, 并且无论打多少通电话, 带子都留在记忆中, 直到闭锁( ) 清除它们 。

      当您调用 colossocket () 或 shut () 关闭 关闭 关闭 输出流时, 您会互相发送 FIN 软件包。 FIN 软件包显示数据传输完整, 计算机会收到 FIN 软件包, 并理解不会再次传送数据 。

      服务端代码

      客户端代码

      参考资料

      套接、连接和绑定功能的细节

      WSASartup是一个100岁的百科全书。

      C/C++ Socket 编程课程:一天的旋套式通信技术

      包括 ws2_32.Lib 图书馆, 视觉演播室 2019 C++ 完成插座通信 。

      C 中的编程插座

      本文由 在线网速测试 整理编辑,转载请注明出处。

          热门文章

          文章分类