VS2015中基于TCP客户端的实现

《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;

}

 

基于libevent库实现TCP客户端和服务端主要是利用其异步事件处理机制,简化网络编程的复杂性。libevent是一个高效的、跨平台的事件驱动框架,特别适合用于实时应用和网络服务器。 **TCP客户端示例**: ```cpp #include <event2/event.h> void on_connect(struct evconnbase *cb, short revents) { if (revents & EV_ERROR) { perror("Connect failed"); return; } struct sockaddr_in server_addr; // ...填充服务器地址... int fd = accept(cb->ev_base->fd, (struct sockaddr *)&server_addr, NULL); if (fd == -1) { perror("Accept failed"); return; } event_set(&client_event, fd, EV_READ | EV_PERSIST, on_read, cb); event_add(&client_event, NULL); } void on_read(struct evconnbase *cb, short revents) { if (revents & EV_TIMEOUT) { fprintf(stderr, "Read timeout\n"); return; } char buf[1024]; ssize_t n = read(cb->fd, buf, sizeof(buf)); if (n <= 0) { if (n == 0) printf("Connection closed by peer\n"); else perror("Read error"); event_del(&client_event); } else { // 发送响应或数据处理 } } int main() { // 初始化libevent event_init(); // 创建连接事件 struct event_base *base = event_base_new(); struct evconnbase *client_event = evconnbase_new(base, on_connect); // 连接服务器,设置超时等 // ...实际连接过程... // 主循环 while (1) { event_base_dispatch(base); } event_base_free(base); event_system_exit(0); } ``` **TCP服务端示例**: ```cpp void on_connection(struct evconnbase *cb, short revents) { if (revents & EV_ERROR) { perror("Connection failed"); return; } struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); int fd = accept(cb->ev_base->fd, (struct sockaddr *)&client_addr, &addr_len); if (fd == -1) { perror("Accept failed"); return;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值