Socket 的创建与连接
Socket 编程的基本操作包括创建和连接 Socket,这些操作是网络通信的基础。以下是有关 Socket 创建与连接的详细说明,包括在不同编程语言中的示例。
1. Socket 的创建
创建 Socket 是指在应用程序中创建一个用于网络通信的端点。创建 Socket 的步骤如下:
- 选择 Socket 类型:确定使用的套接字类型,如流式 Socket(SOCK_STREAM)用于 TCP 通信,数据报 Socket(SOCK_DGRAM)用于 UDP 通信。
- 调用系统函数:使用系统提供的函数创建 Socket 实例。
Python 示例
import socket
# 创建一个 TCP 套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
C++ 示例
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
int main() {
// 创建一个 TCP 套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket");
return 1;
}
return 0;
}
2. Socket 的绑定(仅服务器端)
绑定 Socket 是将 Socket 绑定到特定的 IP 地址和端口号。此步骤通常仅在服务器端执行,用于指定服务器监听的地址和端口。
Python 示例
import socket
# 创建一个 TCP 套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定到 IP 地址和端口
sock.bind(('localhost', 12345))
C++ 示例
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstring>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有网络接口
server_addr.sin_port = htons(12345); // 端口号
if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind");
return 1;
}
return 0;
}
3. Socket 的监听(仅服务器端)
监听 Socket 是使服务器端的 Socket 进入监听状态,准备接受客户端的连接请求。
Python 示例
# 监听连接请求
sock.listen(5) # 允许最多 5 个连接排队
C++ 示例
if (listen(sockfd, 5) < 0) {
perror("listen");
return 1;
}
4. Socket 的连接(客户端)
连接到服务器 是客户端通过 Socket 连接到服务器端的 IP 地址和端口。
Python 示例
# 创建一个 TCP 套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到服务器
sock.connect(('localhost', 12345))
C++ 示例
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr);
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("connect");
return 1;
}
return 0;
}
5. Socket 的接受(仅服务器端)
接受连接 是服务器端接受客户端的连接请求,并创建一个新的 Socket 用于与客户端通信。
Python 示例
# 接受客户端连接
client_socket, client_address = sock.accept()
C++ 示例
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <cstring>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(12345);
bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
listen(sockfd, 5);
int client_sockfd = accept(sockfd, nullptr, nullptr);
if (client_sockfd < 0) {
perror("accept");
return 1;
}
return 0;
}
6. Socket 关闭
在通信结束后,应关闭 Socket 以释放资源。
Python 示例
# 关闭 Socket
sock.close()
C++ 示例
close(sockfd);
总结
Socket 的创建与连接是网络编程的基础步骤:
- 创建 Socket:通过系统调用创建网络端点。
- 绑定 Socket(服务器端):将 Socket 绑定到指定的 IP 地址和端口。
- 监听(服务器端):使 Socket 进入监听状态,等待连接请求。
- 连接(客户端):连接到服务器端的指定 IP 地址和端口。
- 接受连接(服务器端):接受客户端的连接请求,并建立新的 Socket。
- 关闭 Socket:结束通信并释放资源。
这些操作构成了网络应用程序的基础,通过正确使用这些操作,可以实现各种网络通信功能。