您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C++ Socket网络编程方法是什么
## 1. Socket编程基础概念
Socket(套接字)是网络通信的基石,它允许不同主机或同一主机的不同进程之间进行数据交换。在C++中,我们通常使用Berkeley Socket API(BSD Socket)进行网络编程。
### 1.1 Socket类型
- **流式Socket(SOCK_STREAM)**:面向连接的TCP通信
- **数据报Socket(SOCK_DGRAM)**:无连接的UDP通信
- **原始Socket(SOCK_RAW)**:底层协议访问
### 1.2 基本通信流程
客户端:创建Socket -> 连接服务器 -> 发送/接收数据 -> 关闭连接 服务器:创建Socket -> 绑定地址 -> 监听连接 -> 接受连接 -> 发送/接收数据 -> 关闭连接
## 2. 核心API详解
### 2.1 基础函数
```cpp
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// 创建socket
int socket(int domain, int type, int protocol);
// 绑定地址
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 监听连接
int listen(int sockfd, int backlog);
// 接受连接
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 建立连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
// 发送数据
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
// 接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
// IPv4地址结构
struct sockaddr_in {
sa_family_t sin_family; // 地址族(AF_INET)
in_port_t sin_port; // 端口号
struct in_addr sin_addr; // IP地址
};
// IPv6地址结构
struct sockaddr_in6 {
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};
#include <iostream>
#include <cstring>
#include <unistd.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
// 创建socket文件描述符
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FLURE);
}
// 设置socket选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FLURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// 绑定socket到端口
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FLURE);
}
// 开始监听
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FLURE);
}
// 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FLURE);
}
// 读取客户端数据
read(new_socket, buffer, BUFFER_SIZE);
printf("Client says: %s\n", buffer);
// 发送响应
const char *hello = "Hello from server";
send(new_socket, hello, strlen(hello), 0);
printf("Hello message sent\n");
// 关闭连接
close(new_socket);
close(server_fd);
return 0;
}
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
const char *hello = "Hello from client";
char buffer[1024] = {0};
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
// 转换IP地址
if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
// 连接服务器
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
// 发送数据
send(sock, hello, strlen(hello), 0);
printf("Hello message sent\n");
// 接收响应
read(sock, buffer, 1024);
printf("Server says: %s\n", buffer);
close(sock);
return 0;
}
#include <iostream>
#include <cstring>
#include <arpa/inet.h>
#define PORT 8080
#define MAXLINE 1024
int main() {
int sockfd;
char buffer[MAXLINE];
struct sockaddr_in servaddr, cliaddr;
// 创建UDP socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FLURE);
}
memset(&servaddr, 0, sizeof(servaddr));
memset(&cliaddr, 0, sizeof(cliaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
// 绑定socket
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("bind failed");
exit(EXIT_FLURE);
}
socklen_t len;
int n;
len = sizeof(cliaddr);
// 接收数据
n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WTALL,
(struct sockaddr *)&cliaddr, &len);
buffer[n] = '\0';
printf("Client : %s\n", buffer);
// 发送响应
const char *hello = "Hello from server";
sendto(sockfd, (const char *)hello, strlen(hello), MSG_CONFIRM,
(const struct sockaddr *)&cliaddr, len);
printf("Hello message sent.\n");
return 0;
}
#include <thread>
#include <vector>
void handle_client(int client_socket) {
char buffer[1024] = {0};
read(client_socket, buffer, 1024);
printf("Received: %s\n", buffer);
const char *response = "Message received";
send(client_socket, response, strlen(response), 0);
close(client_socket);
}
int main() {
// ... (服务器初始化代码同前)
while (true) {
int new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
if (new_socket < 0) {
perror("accept");
continue;
}
std::thread(handle_client, new_socket).detach();
}
close(server_fd);
return 0;
}
C++ Socket编程是构建网络应用的基础,掌握TCP/UDP通信模型、理解socket API的使用方法,并遵循最佳实践,可以开发出高效可靠的网络应用程序。现代C++项目通常会使用更高级的网络库(如Boost.Asio)来简化开发,但理解底层socket工作原理仍然至关重要。 “`
这篇文章涵盖了C++ Socket编程的核心内容,包括: 1. 基础概念和通信流程 2. 关键API详解 3. TCP/UDP服务器和客户端实现 4. 多线程处理 5. 错误处理和跨平台注意事项
总字数约1350字,采用Markdown格式,包含代码示例和结构化内容。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。