Table of Contents
准备工作
Windows网络编程一般是指 Windows Socket
编程(winsocket),它从UNIX Socket
发展而来。进行Windows网络编程,首先需要添加依赖库WS2_32.lib
或 WSOCK_32.lib
,加载动态库ws2_32.dll,放入C:/Windows/System32。然后使用时在源文件中包含头文件:
#include <WinSock2.h>
// #include <MSWSOCK.h>
// #include <winsock.h>
说明:
有些接口已经弃用,采用新的接口,具体是哪些,后面会慢慢指出。
- 如何引入依赖库?
#pragma comment(lib, "ws2_32.lib"); // 源文件中添加
也可以在配置文件中添加:属性----链接器----输入----ws2_32.lib.
socket
socket
套接字是应用层到传输层的接口,表示一个连接的两端,每个端由IP地址和端口port组成,即socket是由两端点的ip和端口port组成的
。
-
套接字类型 SOCKET 定义
typedef unsigned int SOCKET; // 句柄
-
端口
端口是传输层的概念,每个端口对应一个 process 进程,因此一条连接表示一个进程与另一个进程建立联系。
-
套接字类型
一般使用两种套接字:TCP 流套接字,UDP 数据报套接字。前者提供可靠的、无重复的、有序的数据流服务,后者提供不可靠传输。
C/S模式
winsocket
一般采用C/S模式
- Server 端流程
1、初始化winsocket
2、建立socket
3、绑定服务端地址(bind)
4、开始监听(listen)
5、然后与客户端建立连接(accept)
6、然后与客户端进行通信(send, recv)
7、当通信完成以后,关闭连接
8、释放winsocket的有关资源
- Client 端流程
1、初始化winsocket
2、建立socket
3、与服务器进行连接(connect)
4、与服务器进行通信(send, recv)
5、当通信完成以后,关闭连接
6、释放winsocket占用的资源
话不多说,先上一段代码,再小段分析
源代码
源码亲测可以运行
服务端
// win_server.cpp
// compiler with: VS2017
#include "pch.h"
#include <stdio.h>
#include <winsock2.h> // 必须包含windwos.h之前
#include <Windows.h>
// #include <process.h> /* _beginthreadex */
// 指定依赖库目录
#pragma comment(lib,"ws2_32.lib")
// 设置端口号
constexpr auto PORT = 6000;
// C/S 端连接情况分析
// Server 端收发数据情况
DWORD WINAPI clientProc(LPARAM lparam)
{
SOCKET sockClient = (SOCKET)lparam;
char buf[1024];
while (TRUE)
{
memset(buf, 0, sizeof(buf));
// 接收客户端的一条数据
int ret_recv = recv(sockClient, buf, sizeof(buf), 0);
//检查是否接收失败
if (SOCKET_ERROR == ret_recv)
{
printf("socket recv failed\n");
closesocket(sockClient);
return -1;
}
// 0 代表客户端主动断开连接
if (ret_recv == 0)
{
printf("client close connection\n");
closesocket(sockClient);
return -1;
}
// 发送数据
int ret_send = send(sockClient, buf, strlen(buf), 0);
//检查是否发送失败
if (SOCKET_ERROR == ret_send)
{
printf("socket send failed\n");
closesocket(sockClient)