Socket网络编程
更新: 10/23/2026 字数: 0 字 时长: 0 分钟
socket是内核向应用层提供的一套网络编程接口,用户基于 socket 接口可开发自己的网络相关应用程序。
主要函数介绍
创建套接字
c
int socket(int domain, int type, int protocol);domain:指定协议族,常用的有:AF_INET:IPv4AF_INET6:IPv6
- type:指定套接字类型:
SOCK_STREAM:面向连接(TCP)SOCK_DGRAM:无连接(UDP)
protocol:指定协议类型,通常设为 0 表示根据 domain 和 type 自动选择协议。
绑定端口
c
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);sockfd:由socket函数返回的文件描述符。addr:指向包含本地 IP 和端口号的sockaddr结构体。addrlen:addr结构体的大小,通常使用sizeof(struct sockaddr_in)。
c
struct sockaddr {
unsigned short sa_family; // 地址族(如 AF_INET)
char sa_data[14]; // 协议地址(通常不直接使用)
};由于系统的兼容性,一般使用 struct sockaddr_in 来替代
c
struct sockaddr_in {
unsigned short sin_family; // 地址族,必须为 AF_INET
unsigned short sin_port; // 端口号,使用 htons() 转换
struct in_addr sin_addr; // IPv4 地址,设置为 INADDR_ANY 表示可以和任何的主机通信
unsigned char sin_zero[8];// 填充字节,保持与 sockaddr 长度一致
};
struct in_addr {
in_addr_t s_addr; // IPv4 地址(以网络字节序存储)
};监听连接(TCP)
c
int listen(int sockfd, int backlog);sockfd:套接字描述符,必须是 SOCK_STREAM 类型。backlog:等待连接队列的最大长度。
接受连接(TCP)
c
int accept(int sockfd, struct sockaddr *addr, int *addrlen);sockfd:监听套接字。addr:用于接收客户端地址信息。addrlen:输入输出参数,调用前设置为addr的大小,调用后包含实际地址大小。
发起连接(TCP 客户端)
c
int connect(int sockfd, struct sockaddr *addr, int addrlen);sockfd:由socket创建的客户端套接字。addr:目标服务器地址。addrlen:地址结构大小。
发送与接收数据(TCP)
c
ssize_t send(int sockfd, void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);sockfd:套接字描述符。buf:发送或接收数据的缓冲区。len:缓冲区大小。flags:通常为 0,可设为MSG_OOB(紧急数据)、MSG_PEEK(窥视)等。
发送与接收数据(UDP)
c
ssize_t sendto(int sockfd, void *buf, size_t len, int flags, struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);sendto中:dest_addr:目标地址结构体。addrlen:目标地址结构体大小,常置为sezeof(struct sockaddr)。
recvfrom中:src_addr:用于接收发送者地址。addrlen:接收地址长度,常置为sezeof(struct sockaddr)。
TCP 编程
TCP 是一种面向连接、可靠的协议,适用于传输稳定性要求高的应用。
TCP 服务器示例
c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sockfd, 5);
int client_fd = accept(sockfd, NULL, NULL);
char buffer[1024];
int len = recv(client_fd, buffer, sizeof(buffer), 0);
buffer[len] = '\0';
printf("Received: %s\n", buffer);
send(client_fd, "Hello Client", 12, 0);
close(client_fd);
close(sockfd);
return 0;
}TCP 客户端示例
c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
send(sockfd, "Hello Server", 12, 0);
char buffer[1024];
int len = recv(sockfd, buffer, sizeof(buffer), 0);
buffer[len] = '\0';
printf("Received: %s\n", buffer);
close(sockfd);
return 0;
}UDP 编程
UDP 是一种无连接、不保证可靠性的协议,适用于对实时性要求高的应用,如视频、语音传输。
UDP 服务器示例
c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket 创建失败");
exit(EXIT_FAILURE);
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
perror("绑定端口失败");
close(sockfd);
exit(EXIT_FAILURE);
}
struct sockaddr_in client;
socklen_t client_len = sizeof(client);
char buffer[1024];
while (1)
{
ssize_t len = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client, &client_len);
if (len == -1) {
perror("数据接收失败");
} else if (len == 0) {
printf("收到空数据报\n"); // UDP 允许长度为 0 的数据报
} else {
buffer[len] = '\0'; // 安全终止字符串
printf("收到消息: %s\n", buffer);
//6. 发送响应(动态计算长度)
const char *response = "Hello Client";
ssize_t sent_bytes = sendto(sockfd, response, strlen(response),0, (struct sockaddr*)&client, client_len);
if (sent_bytes == -1) {
perror("响应发送失败");
}
}
}
close(sockfd);
return 0;
}UDP 客户端示例
c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
int main() {
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
socklen_t addrlen = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
sendto(sockfd, "Hello Server", 12, 0, (struct sockaddr*)&addr, addrlen);
char buffer[1024];
int len = recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);
buffer[len] = '\0';
printf("Received: %s\n", buffer);
close(sockfd);
return 0;
}