[toc]

用C语言在Linux中使用UDP协议发送文本消息

1.用C语言在Linux中使用UDP协议发送一句文本消息

1.使用C语言在Linux中创建服务端程序接收一句文本消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in, inet_ntop
#include <errno.h>

#define BUF_SIZE 256

int main() {
int sock;
struct sockaddr_in serverAddr, clientAddr;
char buffer[BUF_SIZE];
socklen_t clientAddrLen = sizeof(clientAddr);

// 创建 UDP 套接字
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Socket creation failed");
return 1;
}

// 填充服务器地址信息
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888); // 监听端口
serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有可用的接口

// 绑定套接字到地址
if (bind(sock, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) < 0) {
perror("Bind failed");
close(sock);
return 1;
}

printf("UDP server is listening on port 8888...\n");

// 接收一次消息
int recvLen = recvfrom(sock, buffer, BUF_SIZE, 0, (struct sockaddr*)&clientAddr, &clientAddrLen);
if (recvLen < 0) {
perror("Receive failed");
close(sock);
return 1;
}

// 将接收到的消息以 null 结尾
buffer[recvLen] = '\0';

// 打印接收到的消息
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clientAddr.sin_addr, clientIP, sizeof(clientIP));
printf("Received message from %s:%d\n", clientIP, ntohs(clientAddr.sin_port));
printf("%s\n", buffer);

// 关闭套接字
close(sock);
return 0;
}

2.使用C语言在Linux中创建客户端程序发送一句文本消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// LinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in, inet_pton
#include <errno.h>

#define BUF_SIZE 256

int main() {
int sock;
struct sockaddr_in serverAddr;
char message[BUF_SIZE];

// 创建 UDP 套接字
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Socket creation failed");
return 1;
}

// 填充目标地址信息
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888); // 目标端口
serverAddr.sin_addr.s_addr = INADDR_ANY; // 目标地址(可以是127.0.0.1)

// 使用 inet_pton 替代 inet_addr
if (inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sock);
return 1;
}

// 输入要发送的消息
printf("Enter message to send: ");
fgets(message, BUF_SIZE, stdin);

// 发送消息
ssize_t sendResult = sendto(sock, message, strlen(message), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if (sendResult < 0) {
perror("Send failed");
close(sock);
return 1;
}

printf("Message sent: %s\n", message);

// 关闭套接字
close(sock);
return 0;
}

3.运行结果

  1. 运行LinServer
  2. 运行LinClient
  3. 运行成功

2.用C语言在Linux中使用UDP协议多次发送文本消息

1.使用C语言在Linux中创建服务端程序多次接收文本消息

在 UDP 协议中,”断开连接” 的概念与 TCP 不同,因为 UDP 是无连接的。UDP 服务器无法主动检测客户端的断开状态,因为它不维护连接状态。UDP 服务器只能在接收到数据包时进行响应。

不过,可以通过约定某种特定的消息(例如,客户端发送一个特定的 “断开连接” 消息)来模拟这种行为。以下是修改后的代码示例,当接收到特定消息(例如 “exit”)时,服务器将退出循环并关闭连接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in, inet_ntop
#include <errno.h>

int main() {
int serverSocket;
struct sockaddr_in server, client;
socklen_t clientSize;
char buffer[1024];
ssize_t recvSize;

// 创建 socket
serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (serverSocket < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有可用的接口
server.sin_port = htons(8888); // 服务器端口

// 绑定 socket
if (bind(serverSocket, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Bind failed");
close(serverSocket);
return 1;
}

printf("Waiting for incoming messages...\n");

clientSize = sizeof(client);
// 接收消息
while (1) {
recvSize = recvfrom(serverSocket, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client, &clientSize);
if (recvSize < 0) {
perror("Receive failed");
break;
}

buffer[recvSize] = '\0'; // 添加字符串结束符
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client.sin_addr, clientIP, sizeof(clientIP)); // 使用 inet_ntop
printf("Received message from %s:%d: %s\n", clientIP, ntohs(client.sin_port), buffer);

// 检查是否收到 "exit" 消息
if (strcmp(buffer, "exit") == 0) {
printf("Client requested to exit. Closing server.\n");
break; // 退出循环
}
}

// 关闭 socket
close(serverSocket);
return 0;
}

2.使用C语言在Linux中创建客户端程序多次发送文本消息

此程序当输入exit时,先发送消息给服务端再退出程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// LinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in, inet_pton
#include <errno.h>

void sendMessage(int sock, struct sockaddr_in *server, const char *message) {
ssize_t sendResult = sendto(sock, message, strlen(message), 0, (struct sockaddr*)server, sizeof(*server));
if (sendResult < 0) {
perror("Send failed");
} else {
printf("Message sent: %s\n", message);
}
}

int main() {
int sock;
struct sockaddr_in server;
char message[1024];

// 创建 socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_port = htons(8888); // 服务器端口

// 使用 inet_pton 将 IP 地址转换为网络字节顺序
if (inet_pton(AF_INET, "127.0.0.1", &server.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sock);
return 1;
}

// 发送多条消息
while (1) {
printf("Enter message (type 'exit' to quit): ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = 0; // 去掉换行符

// 检查是否退出
if (strcmp(message, "exit") == 0) {
// 发送退出消息
sendMessage(sock, &server, "exit");
break; // 退出循环
}

// 发送消息
sendMessage(sock, &server, message);
}

// 关闭 socket
close(sock);
return 0;
}

3.运行结果

  1. 运行LinServer

  2. 运行LinClient

  3. 运行成功

3.用C语言在Linux中使用UDP协议客户端退出后可以再次连接服务器

1.使用C语言在Linux中创建服务端程序断开后等待客户端连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for sockaddr_in, inet_ntop
#include <errno.h>

int main() {
int serverSocket;
struct sockaddr_in server, client;
socklen_t clientSize;
char buffer[1024];
ssize_t recvSize;

// 创建 socket
serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (serverSocket < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有可用的接口
server.sin_port = htons(8888); // 服务器端口

// 绑定 socket
if (bind(serverSocket, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Bind failed");
close(serverSocket);
return 1;
}

printf("Waiting for incoming messages...\n");
clientSize = sizeof(client);

// 循环接收消息
while (1) {
// 接收消息
recvSize = recvfrom(serverSocket, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client, &clientSize);
if (recvSize < 0) {
perror("Receive failed");
continue;
}

buffer[recvSize] = '\0'; // 添加字符串结束符
char clientIP[INET_ADDRSTRLEN]; // 用于存储客户端 IP 地址
inet_ntop(AF_INET, &client.sin_addr, clientIP, sizeof(clientIP)); // 使用 inet_ntop
printf("Received message from %s:%d: %s\n", clientIP, ntohs(client.sin_port), buffer);
}

// 关闭服务器 socket
close(serverSocket);
return 0;
}

2.使用C语言在Linux中创建客户端程序退出后再次连接服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// LinuxClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for inet_pton() and sockaddr_in
#include <sys/types.h>
#include <sys/socket.h>

int main() {
int sock;
struct sockaddr_in server;
char message[1024];
ssize_t sendResult;

// 创建 socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_port = htons(8888); // 服务器端口

// 使用 inet_pton 将 IP 地址转换为网络字节顺序
if (inet_pton(AF_INET, "127.0.0.1", &server.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sock);
return 1;
}

// 发送多条消息
while (1) {
printf("Enter message (type 'exit' to quit): ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = 0; // 去掉换行符

// 检查是否退出
if (strcmp(message, "exit") == 0) {
break;
}

// 发送消息
sendResult = sendto(sock, message, strlen(message), 0, (struct sockaddr*)&server, sizeof(server));
if (sendResult < 0) {
perror("Send failed");
break;
} else {
printf("Message sent: %s\n", message);
}
}

// 关闭 socket
close(sock);
return 0;
}

3.运行结果

  1. 运行LinServer

  2. 运行LinClient

  3. 运行成功

4.用C语言在Linux中使用UDP协议让客户端与服务端相互发送文本消息

1.使用C语言在Linux中创建服务端接收文本消息后再发送到客户端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for inet_ntop() and sockaddr_in
#include <sys/types.h>
#include <sys/socket.h>

int main() {
int serverSocket;
struct sockaddr_in server, client;
socklen_t clientSize;
char buffer[1024];
ssize_t recvSize;

// 创建 socket
serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (serverSocket < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY; // 监听所有可用的接口
server.sin_port = htons(8888); // 服务器端口

// 绑定 socket
if (bind(serverSocket, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Bind failed");
close(serverSocket);
return 1;
}

printf("Waiting for incoming messages...\n");
clientSize = sizeof(client);

// 循环接收消息
while (1) {
// 接收消息
recvSize = recvfrom(serverSocket, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client, &clientSize);
if (recvSize < 0) {
perror("Receive failed");
continue;
}

buffer[recvSize] = '\0'; // 添加字符串结束符
char clientIP[INET_ADDRSTRLEN]; // 用于存储客户端 IP 地址
inet_ntop(AF_INET, &client.sin_addr, clientIP, sizeof(clientIP)); // 使用 inet_ntop
printf("Received message from %s:%d: %s\n", clientIP, ntohs(client.sin_port), buffer);

// 发送回客户端
sendto(serverSocket, buffer, recvSize, 0, (struct sockaddr*)&client, clientSize);
}

// 关闭服务器 socket
close(serverSocket);
return 0;
}

2.使用C语言在Linux中创建客户端程序接收与发送文本消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// LinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h> // for inet_pton() and sockaddr_in
#include <sys/types.h>
#include <sys/socket.h>

int main() {
int sock;
struct sockaddr_in server;
char message[1024];
char buffer[1024];
ssize_t sendResult, recvSize;

// 创建 socket
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("Could not create socket");
return 1;
}

// 设置服务器信息
server.sin_family = AF_INET;
server.sin_port = htons(8888); // 服务器端口

// 使用 inet_pton 将 IP 地址转换为网络字节顺序
if (inet_pton(AF_INET, "127.0.0.1", &server.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sock);
return 1;
}

// 发送和接收消息
while (1) {
printf("Enter message (type 'exit' to quit): ");
fgets(message, sizeof(message), stdin);
message[strcspn(message, "\n")] = 0; // 去掉换行符

// 检查是否退出
if (strcmp(message, "exit") == 0) {
break;
}

// 发送消息
sendResult = sendto(sock, message, strlen(message), 0, (struct sockaddr*)&server, sizeof(server));
if (sendResult < 0) {
perror("Send failed");
break;
} else {
printf("Message sent: %s\n", message);
}

// 接收来自服务器的消息
recvSize = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, NULL, NULL);
if (recvSize > 0) {
buffer[recvSize] = '\0'; // 添加字符串结束符
printf("Received from server: %s\n", buffer);
} else if (recvSize < 0) {
perror("Receive failed");
break;
}
}

// 关闭 socket
close(sock);
return 0;
}

3.运行结果

  1. 运行LinServer

  2. 运行LinClient

  3. 运行成功

5.用C语言在Linux中使用UDP协议写一个聊天室让两个客户端之间可以相互发送文本消息

1.使用C语言在Linux中创建服务端接收与转发文本消息到所有客户端中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_CLIENTS 10

int main() {
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len = sizeof(client_addr);
struct sockaddr_in clients[MAX_CLIENTS]; // 存储客户端地址
int client_count = 0;
int first_message[MAX_CLIENTS] = {0}; // 用于跟踪每个客户端是否发送了初始消息

// 创建 UDP 套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}

// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY; // 监听所有可用的接口
server_addr.sin_port = htons(PORT);

// 绑定套接字
if (bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}

// 接收数据并转发
while (1) {
int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
buffer[n] = '\0';

// 检查客户端是否已在列表中
int found = 0;
int client_index = -1;
for (int i = 0; i < client_count; i++) {
if (clients[i].sin_addr.s_addr == client_addr.sin_addr.s_addr &&
clients[i].sin_port == client_addr.sin_port) {
found = 1;
client_index = i;
break;
}
}

// 如果是新客户端,添加到列表
if (!found && client_count < MAX_CLIENTS) {
clients[client_count++] = client_addr;
client_index = client_count - 1; // 新客户端的索引
printf("New client added: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}

// 只转发非初始消息
if (client_index != -1) {
if (first_message[client_index] == 0) {
// 如果是第一次消息,标记为已接收
first_message[client_index] = 1;
} else {
// 转发消息给所有已连接的客户端
for (int i = 0; i < client_count; i++) {
if (clients[i].sin_addr.s_addr != client_addr.sin_addr.s_addr ||
clients[i].sin_port != client_addr.sin_port) {
sendto(sockfd, buffer, n, 0, (const struct sockaddr *)&clients[i], sizeof(clients[i]));
}
}
}
}
}

close(sockfd);
return 0;
}

2.使用C语言在Linux中创建客户端程序接收与发送文本消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//LinuxClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define PORT 8080
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024

// 接收消息的线程函数
void *receive_messages(void *sockfd) {
int socket_fd = *(int *)sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr;
socklen_t addr_len = sizeof(server_addr);

while (1) {
int n = recvfrom(socket_fd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s\n", buffer);
}
}
return NULL;
}

int main() {
int sockfd;
struct sockaddr_in server_addr;

// 创建 UDP 套接字
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}

// 设置服务器地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

// 发送初始消息以注册客户端
const char *initial_message = "Hello, server!";
sendto(sockfd, initial_message, strlen(initial_message), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr));

// 创建接收线程
pthread_t recv_thread;
if (pthread_create(&recv_thread, NULL, receive_messages, (void *)&sockfd) != 0) {
perror("Failed to create thread");
close(sockfd);
exit(EXIT_FAILURE);
}

// 主线程负责发送消息
char message[BUFFER_SIZE];
while (1) {
printf("Enter message: ");
fgets(message, BUFFER_SIZE, stdin);
// 去掉换行符
message[strcspn(message, "\n")] = 0;
sendto(sockfd, message, strlen(message), 0, (const struct sockaddr *)&server_addr, sizeof(server_addr));
}

// 清理资源
pthread_join(recv_thread, NULL);
close(sockfd);
return 0;
}

3.运行结果

  1. 运行LinServer

  2. 运行LinClient

  3. 运行第二个LinClient

  4. 在LinuxClient中输入消息,在另一个LinuxClient中查看接收到的消息。

  5. 运行后的结果符合预期

6.用C语言在Linux中使用UDP协议与ipv6协议发送一句文本消息

1.使用C语言在Linux中使用ipv6地址创建服务端程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//LinServer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h>
#include <netdb.h>

#define PORT "8080" // 服务器端口
#define BUF_SIZE 1024 // 缓冲区大小

int main() {
int sockfd;
struct addrinfo hints, *res;
struct sockaddr_storage client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[BUF_SIZE];
ssize_t recvResult;

// 设置addrinfo结构
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6; // 使用IPv6
hints.ai_socktype = SOCK_DGRAM; // UDP
hints.ai_flags = AI_PASSIVE; // 服务器使用

// 获取地址信息
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo failed");
return 1;
}

// 创建socket
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) {
perror("socket failed");
freeaddrinfo(res);
return 1;
}

// 绑定socket
if (bind(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
perror("bind failed");
close(sockfd);
freeaddrinfo(res);
return 1;
}

freeaddrinfo(res); // 释放addrinfo结构

printf("UDP Server is listening on port %s...\n", PORT);

// 接收消息
while (1) {
recvResult = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client_addr, &addr_len);
if (recvResult < 0) {
perror("recvfrom failed");
continue;
}

buffer[recvResult] = '\0'; // 添加字符串结束符
printf("Received message: %s\n", buffer);

// 发送回客户端
sendto(sockfd, buffer, recvResult, 0, (struct sockaddr*)&client_addr, addr_len);
}

// 关闭socket
close(sockfd);
return 0;
}

2.使用C语言在Linux中使用ipv6地址创建客户端程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//LinClient.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> // for close()
#include <arpa/inet.h>
#include <netdb.h>

#define PORT "8080" // 服务器端口
#define SERVER_ADDR "::1" // 服务器地址(本地IPv6地址)
#define BUF_SIZE 256 // 缓冲区大小

int main() {
int sockfd;
struct addrinfo hints, *res;
const char* message = "Hello, UDP Server!";
ssize_t sendResult;

// 设置addrinfo结构
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6; // 使用IPv6
hints.ai_socktype = SOCK_DGRAM; // UDP
hints.ai_flags = 0;

// 获取服务器地址信息
if (getaddrinfo(SERVER_ADDR, PORT, &hints, &res) != 0) {
perror("getaddrinfo failed");
return 1;
}

// 创建socket
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sockfd < 0) {
perror("socket failed");
freeaddrinfo(res);
return 1;
}

// 发送消息
sendResult = sendto(sockfd, message, strlen(message), 0, res->ai_addr, res->ai_addrlen);
if (sendResult < 0) {
perror("sendto failed");
close(sockfd);
freeaddrinfo(res);
return 1;
}

printf("Message sent: %s\n", message);

// 接收来自服务器的消息
char buffer[BUF_SIZE];
struct sockaddr_storage from_addr;
socklen_t addr_len = sizeof(from_addr);
ssize_t recvResult = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&from_addr, &addr_len);
if (recvResult > 0) {
buffer[recvResult] = '\0'; // 添加字符串结束符
printf("Received from server: %s\n", buffer);
} else {
perror("recvfrom failed");
}

// 关闭socket
close(sockfd);
freeaddrinfo(res);
return 0;
}

3.运行结果

  1. 运行LinServer

  2. 运行LinClient

  3. 运行成功