C++IP协议通信
1. TCP协议通信
1.1 服务端实现
创建套接字
使用socket(AF_INET, SOCK_STREAM, 0)
创建TCP套接字。其中,AF_INET
表示使用IPv4协议族,SOCK_STREAM
表示使用TCP协议,0
表示让系统自动选择默认的协议。
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
绑定地址
通过bind
将套接字绑定到本地地址和端口。绑定时需要指定本地的IP地址和端口号,通常使用INADDR_ANY
表示绑定到所有可用的网络接口。
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8080);
if (bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("bind failed");
exit(EXIT_FAILURE);
}
监听连接
调用listen
函数开始监听客户端连接请求。listen
函数的第二个参数backlog
表示等待连接的队列长度,通常设置为SOMAXCONN
。
if (listen(listenfd, SOMAXCONN) == -1) {
perror("listen failed");
exit(EXIT_FAILURE);
}
接受连接
使用accept
函数接受客户端连接,返回新的套接字用于通信。accept
函数会阻塞,直到有客户端连接请求到达。
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int clientfd = accept(listenfd, (struct sockaddr*)&client_addr, &client_len);
if (clientfd == -1) {
perror("accept failed");
exit(EXIT_FAILURE);
}
数据传输
通过send
和recv
函数与客户端进行数据交互。send
函数用于向客户端发送数据,recv
函数用于从客户端接收数据。
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
int bytes_received = recv(clientfd, buffer, sizeof(buffer), 0);
if (bytes_received > 0) {
printf("Received data: %s\n", buffer);
send(clientfd, buffer, bytes_received, 0);
} else {
perror("recv failed");
}
关闭连接
通信结束后调用close
关闭套接字。
close(clientfd);
close(listenfd);
1.2 客户端实现
创建套接字
使用socket(AF_INET, SOCK_STREAM, 0)
创建TCP套接字。
int clientfd = socket(AF_INET, SOCK_STREAM, 0);
if (clientfd == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
连接服务器
通过connect
函数向服务器发起连接请求。需要指定服务器的IP地址和端口号。
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8080);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(clientfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("connect failed");
exit(EXIT_FAILURE);
}
数据传输
使用send
和recv
函数与服务器进行数据交互。
char send_buffer[] = "Hello, Server!";
send(clientfd, send_buffer, strlen(send_buffer), 0);
char recv_buffer[1024];
memset(recv_buffer, 0, sizeof(recv_buffer));
int bytes_received = recv(clientfd, recv_buffer, sizeof(recv_buffer), 0);
if (bytes_received > 0) {
printf("Received data: %s\n", recv_buffer);
} else {
perror("recv failed");
}
关闭连接
通信结束后调用close
关闭套接字。
close(clientfd);
1.3 示例代码
服务端代码示例
#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;
int main() {
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(8080);
if (bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(listenfd, SOMAXCONN) == -1) {
perror("listen failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int clientfd = accept(listenfd, (struct sockaddr*)&client_addr, &client_len);
if (clientfd == -1) {
perror("accept failed");
exit(EXIT_FAILURE);
}
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
int bytes_received = recv(clientfd, buffer, sizeof(buffer), 0);
if (bytes_received > 0) {
printf("Received data: %s\n", buffer);
send(clientfd, buffer, bytes_received, 0);
} else {
perror("recv failed");
}
close(clientfd);
close(listenfd);
return 0;
}
客户端代码示例
#include <iostream>