70 lines
2.1 KiB
C
70 lines
2.1 KiB
C
#include <stdio.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
|
|
int main(int argc, char const *argv[])
|
|
{
|
|
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (sfd < 0)
|
|
{
|
|
perror("socket");
|
|
return -1;
|
|
}
|
|
|
|
// 1. 绑定本地 ip 和端口号
|
|
struct sockaddr_in addr; // sockaddr_in 结构体对象
|
|
bzero(&addr, sizeof(addr));
|
|
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_port = htons(8000); // 当前 Linux 进程的端口号
|
|
addr.sin_addr.s_addr = htonl(INADDR_ANY); // INADDR_ANY 任意连接的 ip 可用
|
|
// inet_pton(AF_INET, "192.168.31.128", &addr.sin_addr.s_addr);
|
|
|
|
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) != 0) // 绑定
|
|
{
|
|
perror("bind");
|
|
}
|
|
else
|
|
{
|
|
printf("bind success\n");
|
|
|
|
// 接收数据
|
|
char buf[128] = ""; // 接收数据的空间
|
|
struct sockaddr_in src_addr; // 数据来源的地址
|
|
socklen_t addr_len;
|
|
while (1)
|
|
{
|
|
// 重置数据
|
|
bzero(&src_addr, sizeof(src_addr));
|
|
bzero(buf, 128);
|
|
|
|
// 接收数据,如果数据未到达,则会阻塞,直到数据到达为止
|
|
socklen_t addr_len = sizeof(src_addr);
|
|
ssize_t len = recvfrom(sfd, buf, 128, 0, (struct sockaddr *)&src_addr, &addr_len);
|
|
if (len < 0)
|
|
{
|
|
perror("recvfrom");
|
|
break;
|
|
}
|
|
|
|
char src_ip[16];
|
|
int src_port = ntohs(src_addr.sin_port); // 将网络字节序转化为主机字节序
|
|
inet_ntop(AF_INET, &src_addr.sin_addr.s_addr, src_ip, 16); // 从 src_addr 取 ip 并转化为字符串赋值给 src_ip
|
|
|
|
printf("从 %s:%d 位置接受到的数据(%ld Bytes): %s\n", src_ip, src_port, len, buf);
|
|
|
|
char buf2[1280];
|
|
sprintf(buf2, "返回: %s\n", buf);
|
|
// 回一句消息
|
|
sendto(sfd, buf2, strlen(buf2), 0, (struct sockaddr *)&src_addr, addr_len);
|
|
}
|
|
}
|
|
|
|
close(sfd);
|
|
|
|
return 0;
|
|
}
|