以下主要以 Linux C++ 为例。

常用头文件

1
2
3
4
5
6
7
8
9
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <cstring>
#include <iostream>

socket()

创建套接字。

1
int socket(int domain, int type, int protocol);

常用参数:

1
int fd = socket(AF_INET, SOCK_STREAM, 0);

含义:

参数 说明
AF_INET IPv4
SOCK_STREAM TCP
0 自动选择协议

UDP:

1
int fd = socket(AF_INET, SOCK_DGRAM, 0);

bind()

绑定本地 IP 和端口。

1
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);

示例:

1
2
3
4
5
6
sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = INADDR_ANY;

bind(sockfd, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));

说明:

  • INADDR_ANY 表示监听本机所有网卡
  • htons() 将端口从主机字节序转为网络字节序

listen()

将 Socket 变成监听状态。

1
int listen(int sockfd, int backlog);

示例:

1
listen(sockfd, SOMAXCONN);

accept()

接受客户端连接。

1
int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen);

示例:

1
2
3
4
sockaddr_in clientAddr{};
socklen_t len = sizeof(clientAddr);

int clientfd = accept(sockfd, reinterpret_cast<sockaddr*>(&clientAddr), &len);

connect()

客户端连接服务器。

1
int connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen);

示例:

1
2
3
4
5
6
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8080);
inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);

connect(sockfd, reinterpret_cast<sockaddr*>(&serverAddr), sizeof(serverAddr));

send() / recv()

TCP 数据发送和接收。

1
2
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);

示例:

1
2
3
4
5
6
7
char buf[1024];

ssize_t n = recv(clientfd, buf, sizeof(buf), 0);

if (n > 0) {
send(clientfd, buf, n, 0);
}

注意:

  • recv() 返回 0 表示对端关闭连接
  • send() 可能只发送部分数据
  • 需要考虑 EINTREAGAIN

sendto() / recvfrom()

UDP 数据发送和接收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ssize_t sendto(
int sockfd,
const void* buf,
size_t len,
int flags,
const 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
);

close()

关闭 Socket。

1
close(sockfd);

setsockopt()

设置 Socket 选项。

常见用途:

端口复用

1
2
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

禁用 Nagle 算法

1
2
3
4
#include <netinet/tcp.h>

int flag = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));