WinSocket API —— TCP\IP连接
要进行网络通信编程,就要用到socket(套接字)。套接字代表一个通信端口,有地址,有端口号,可连接(按类型),可收,可发。
要进行socket编程,要为工程导入库文件,添加头文件,并在程序里加载套接字库。
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib") //2.0版本
#include <winsock.h>
#pragma comment(lib, "wsock32.lib") //1.0版本
winsock是Windows平台下的网络套接字(Socket)接口规范。它从Unix平台的Berkele y(BSD)套接字方案借鉴了许多东西。Winsock是网络编程接口,而不是协议。建立Winsock2规范的主要目的是提供一个与协议无关的传送接口。使用winsock API,可以编写基于各种网络协议(如TCP、UDP、IP)的应用程序。实际上Windows下多数要访问网络的程序其底层都调用了winsock API。winsock2的winsock API的dll文件是ws2_32.dll。
服务端监听过程:
1. 加载套接字库,主要是版本,注意拼接次序。
WSADATA{ wVersion,wHighVersion, iMaxSockets\iMaxUdpDg };
0 == WSAStartup(MAKEWORD(1,2), &WSADATA) ; //载入WinSocket API dll库
w = MAKEWORD(a, b); a = LOBYTE(w); b = HIBYTE(w); //版本2.1,makeword(1,2)
l = MAKELONG(a, b); a = LOWORD(l); b = HIWORD(w);
2. 创建一个服务器端socket,这是一个监听套接字
INVALID_SOCKET(socket类) != socket(AF_INET\UNIX\…, SOCK_STREAM\DGRAM\…, 0); //通信端点
3. 创建一个地址结构体,用bind函数把socket和地址绑定,只有服务器端监听套接字需要绑定:
SOCKADDR_IN{ sin_family, //指定地址家族
sin_port = htons(short),
sin_addr.s_addr = htonl(INADDR_ANY)
= inet_addr("172.29.1.1")
} //inet_ntoa(long)
SOCKET_ERROR(-1) != bind(m_Socket, (struct sockaddr *)&SOCKADDR_IN, sizeof());
4. 设置为监听模式:
listen(m_Socket, SOMAXCONN); //放入等待连接队列,超出的直接丢弃
5. 等待客户端的连接请求:
real_conn_Socket = accept (m_Socket, (SOCKADDR*) &SOCKADDR_IN, &len);
//real_conn_Socket
◆当有客户端请求连接m_Socket,accept 函数就会执行。注意,accept函数返回一个real_conn_Socket,其实当成功连接后,与客户端custom_Socket连接的是real_conn_Socket,而不是m_Socket,进行数据传送的也是real_conn_Socket。简单的说,服务器端m_Socket只负责监听和接收连接请求。
6. 卸载套接字库:
WSACleanup();
客户端请求连接过程:
3. 向服务器端socket发出连接请求:
SOCKADDR_IN{ sin_family, //指定地址家族
sin_port = 服务器端监听套接字bind的端口,
sin_addr.s_addr = 服务器端监听套接字bind的IP
}
connect(custom_Socket, (SOCKADDR*)&SOCKADDR_IN, sizeof(SOCKADDR_IN));
◆客户端socket并不需要绑定IP地址和端口,服务器端socket需要绑定。如果服务器端socket不绑定,客户端socket又知道向哪个IP地址和端口发起连接请求呢?而系统会自动为客户端socket绑定一个随机的端口,服务器只要用accept函数返回的socket与客户端socket交换数据就行了,如果服务器需要查询客户端socket的IP和端口,可以查看accept函数的第二个参数记录的客户端socket地址信息。
以上是连接的操作