在《VS2015中基于TCP服务端的实现》中实现了基于TCP的服务端。服务端通过调用listen()函数将套接字设置为监听模式,并且调用accept()函数等待客户端的连接。在基于TCP的客户端中,主要的流程包括创建客户端套接字和连接服务端两个步骤。
1 创建客户端套接字
通过socket()函数创建用于客户端的套接字。socket()函数的用法请参考《VS2015中基于TCP服务端的实现》。
2 连接服务器
客户端通过调用connect()函数,连接处于监听状态的服务端套接字。
2.1 connect()函数
该函数的格式为
int WSAAPI connect(
SOCKET s
, const sockaddr *name
, int namelen
);
其中,参数s表示客户端的套接字,通过该套接字连接服务端;name是sockaddr结构的指针,该指针指向的内容是要连接的服务端的地址信息,sockaddr结构的相关内容请参考《VS2015中基于TCP服务端的实现》;namelen是name指向内容的大小,单位是字节。如果连接服务端成功,则connect()函数返回值为0,否则返回SOCKET_ERROR。
2.2 相关代码
2.2.1 配置服务端地址信息
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5150);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.11");
其中,变量serverAddr是sockaddr_in结构的变量,用于保存服务端的信息。5150是在《VS2015中基于TCP服务端的实现》中提到的服务端监听的端口。192.168.1.11是服务端IP地址,使用inet_addr()函数将字符串格式的IP地址转换为二进制格式的IP地址。在VS2015中,inet_addr()函数已经被inet_pton()函数所替。inet_addr()函数的使用方法请参见《VS2015中IP地址转换函数》。在VS2015中使用inet_addr()函数时,程序在编译时会报错,解决方法请参考《VS2015套接字编程中_WINSOCK_DEPRECATED_NO_WARNINGS的解决方法》。
2.2.2 连接服务端
int iResult = connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR)
{
printf("连接服务端失败:%ld\n", WSAGetLastError());
iResult = closesocket(clientSocket);
WSACleanup();
return 1;
}
printf("连接服务端成功!\n");
在配置了服务端信息之后,调用connect()函数连接服务端。其中,clientSocket是在“1 创建客户端套接字”中创建的客户端套接字;serverAddr是在“2.2.1 配置服务端地址信息”中配置的服务端信息。如果连接服务端失败,则调用closesocket()函数关闭套接字;如果连接服务端成功,则显示成功的信息。
3 完整代码
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET clientSocket = INVALID_SOCKET;
clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5150);
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.11");
int iResult = connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR)
{
printf("连接服务端失败:%ld\n", WSAGetLastError());
iResult = closesocket(clientSocket);
WSACleanup();
return 1;
}
printf("连接服务端成功!\n");
return 0;
}