socket通信参考
参考:https://blog.csdn.net/qq_36025591/article/details/113964442
#include <sys/ioctl.h> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <iostream> // 打印十六进制报文的函数(用户已实现) void printHexDump(const char *buf, int len) { { std::cout << "原始报文(HEX): "; for (int i = 0; i < len; ++i) { { printf("%02X ", (unsigned char)buf[i]); if ((i + 1) % 16 == 0) std::cout << std::endl; } } std::cout << "\n------------------------" << std::endl; } } int main() { { // 1. 创建 TCP socket,AF_INET是ipv4,SOCK_STREAM是tcp协议 // 1.1 成功返回文件描述符,失败返回-1 int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { { perror("socket 创建失败"); return -1; } } // 2. 给上面的socket绑定并监听(示例绑定到 0.0.0.0:6666) // 2.1 (sockaddr *)&server_addr解释: // 先获取server_addr的指针(即&server_addr),再强制转换成sockaddr_in的指针(即(sockaddr *)&server_addr) // 3 成功返回0 sockaddr_in server_addr{}; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(6666); server_addr.sin_addr.s_addr = inet_addr("0.0.0.0"); if (bind(sockfd, (sockaddr *)&server_addr, sizeof(server_addr)) < 0) { { perror("bind 失败"); close(sockfd); return -1; } } /** * 建立监听 * 参数1:监听的server端socket套接字 * 参数2:最大允许等待挂起的连接数 * 成功返回0,失败返回-1 * */ listen(sockfd, 5); /** * 说明: * 1.TCP服务端依次调用socket()、bind()、listen()之后,就会监听指定的客户端socket地址了 * 2.TCP客户端依次调用socket()、connect()之后就向TCP服务器发送了一个连接请求 * 3.TCP服务器监听到这个请求之后,就会调用accept()函数去接收请求,这样连接就建立好了。 * 4.之后就可以开始网络I/O操作了,即类同于普通文件的读写I/O操作,还是通过socket套接字进行。 */ // 3. 接受客户端连接 /** * 作用:创建一个新的的socket套接字,并返回一个socket描述字。 * 第一个参数为服务器的socket描述字 * 第二个参数为指向struct sockaddr *的指针,用于返回客户端的协议地址 * 第三个参数为客户端协议地址的长度 * 如果accpet成功,那么其返回值是由内核自动生成的一个全新的描述字(newsocket),代表与返回客户的TCP连接。 * accept的第一个参数为服务器的socket描述字,是服务器开始调用socket()函数生成的,称为监听socket描述字;而accept函数返回的是已连接的socket描述字。两个套接字不一样。 * accept 默认是阻塞,意思就是会一直等待直到有客户端连接过来。 */ sockaddr_in client_addr{}; socklen_t client_len = sizeof(client_addr); int client_sock = accept(sockfd, (sockaddr *)&client_addr, &client_len); if (client_sock < 0) { { perror("accept 失败"); close(sockfd); return -1; } } // 4. 使用 ioctl 获取待读取数据大小 int bytes_available = 0; if (ioctl(client_sock, FIONREAD, &bytes_available) < 0) { { perror("ioctl 失败"); close(client_sock); close(sockfd); return -1; } } // 5. 读取报文并打印 int BUFFER_SIZE = 1024; char buffer[BUFFER_SIZE]; // BUFFER_SIZE 建议设为 4096 或更大 ssize_t recv_len = recv(client_sock, buffer, bytes_available, 0); if (recv_len > 0) { { printHexDump(buffer, recv_len); } } else { { std::cerr << "接收错误或连接关闭" << std::endl; } } // 6. 关闭连接 close(client_sock); close(sockfd); return 0; } }

浙公网安备 33010602011771号