c++实现网络通讯,支持 tcp 协议,支持异步
时间: 2023-09-30 21:03:26 浏览: 165
在C++中实现网络通讯,可以使用操作系统提供的socket库。下面是一个简单的示例代码,支持TCP协议和异步通信:
```c++
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cerrno>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
const int BUFFER_SIZE = 1024; // 缓冲区大小
void error_handling(const char* message) {
perror(message);
exit(1);
}
int create_socket() {
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == -1) {
error_handling("socket() error");
}
return sock;
}
void set_nonblock(int sock) {
int flag = fcntl(sock, F_GETFL, 0);
if (flag == -1) {
error_handling("fcntl(F_GETFL) error");
}
if (fcntl(sock, F_SETFL, flag | O_NONBLOCK) == -1) {
error_handling("fcntl(F_SETFL, O_NONBLOCK) error");
}
}
int connect_server(int sock, const char* ip, int port) {
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(ip);
server_addr.sin_port = htons(port);
int ret = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret == -1) {
if (errno == EINPROGRESS) { // 连接正在进行
std::cout << "connecting..." << std::endl;
fd_set write_fds;
FD_ZERO(&write_fds);
FD_SET(sock, &write_fds);
int max_fd = sock + 1;
struct timeval timeout;
timeout.tv_sec = 5; // 超时时间为5秒
timeout.tv_usec = 0;
if (select(max_fd, nullptr, &write_fds, nullptr, &timeout) == -1) {
error_handling("select() error");
}
if (!FD_ISSET(sock, &write_fds)) {
error_handling("connection timeout");
}
} else {
error_handling("connect() error");
}
}
std::cout << "connect success" << std::endl;
return 0;
}
void recv_data(int sock) {
char buffer[BUFFER_SIZE];
while (true) {
memset(buffer, 0, BUFFER_SIZE);
int ret = recv(sock, buffer, BUFFER_SIZE - 1, 0);
if (ret == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) { // 没有数据可读
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
} else {
error_handling("recv() error");
break;
}
} else if (ret == 0) { // 连接被断开
std::cout << "connection closed by server" << std::endl;
break;
} else {
std::cout << "recv: " << buffer << std::endl;
}
}
}
void send_data(int sock) {
std::string message;
char buffer[BUFFER_SIZE];
while (true) {
std::getline(std::cin, message);
if (message == "exit") {
break;
}
memset(buffer, 0, BUFFER_SIZE);
strncpy(buffer, message.c_str(), message.size());
int ret = send(sock, buffer, message.size(), 0);
if (ret == -1) {
error_handling("send() error");
break;
}
}
}
int main(int argc, char* argv[]) {
if (argc != 3) {
std::cerr << "Usage: " << argv[0] << " <IP> <port>" << std::endl;
return 1;
}
int sock = create_socket();
set_nonblock(sock);
connect_server(sock, argv[1], std::atoi(argv[2]));
std::thread t1(recv_data, sock);
std::thread t2(send_data, sock);
t1.join();
t2.join();
close(sock);
return 0;
}
```
上述代码中,我们使用socket函数创建了一个TCP协议的套接字,然后使用fcntl函数将该套接字设置成非阻塞模式。在connect时,如果连接正在进行中,则使用select函数等待连接完成,超时时间为5秒。接着,我们使用两个线程分别处理接收数据和发送数据的任务,实现了异步通信。
阅读全文