一,代码
#include <stdio.h>
#include <sys/socket.h> //socket函数
#include <netinet/in.h> //struct sockaddr_in结构体
#include <string.h> //memset strlen函数
#include <arpa/inet.h> //inpton函数
#include <unistd.h> //close函数
//bind函数
int main(int argc, const char *argv[])
{
int sockfd = socket(AF_INET, SOCK_DGRAM, 0); // 创建套接字,对应头文件(sys/socket.h)
// AF_INET是IPV4的网络协议套接字类型
if (sockfd < 0)
{
perror("socket");
return 0;
}
printf("sockfd=%d\n", sockfd);
// bind 绑定的IP及端口(给发送者绑定固定的IP及端口)我的ubuntu虚拟机
// 使用netinet/in.h函数
struct sockaddr_in my_addr;
memset(&my_addr, 0, sizeof(my_addr)); // 初始化
my_addr.sin_family = AF_INET; // IPV4
my_addr.sin_port = htons(9000); // 端口
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 通配地址
// htonl函数作用:将一个无符号长整型数从网络字节序转换成主机字节顺序
// INADDR_ANY是本地主机IP的意思(发送者的主机)
int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
// 此处my_addr取地址要强转成(struct sockaddr*)类型,记住
if (ret < 0)
{
perror("bind");
return 0;
}
// 发送数据sendto
struct sockaddr_in dst_addr;
memset(&dst_addr, 0, sizeof(dst_addr));
dst_addr.sin_family = AF_INET; // TPV4套接字类型
dst_addr.sin_port = htons(8000); // 端口号
inet_pton(AF_INET, "192.168.31.37", &dst_addr.sin_addr.s_addr);
// inet_pton函数:将地址赋值到要发送的收件者的地址结构体中(收件者的IP地址)
char buf[] = "你好,大帅逼";
sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
close(sockfd);
return 0;
}
二,详解
这段代码是一个简单的UDP客户端程序,用于向指定的目标IP地址和端口发送数据。下面是对代码的详细解读:
-
引入必要的头文件:
stdio.h
:标准输入输出库。sys/socket.h
:提供套接字函数的定义。netinet/in.h
:定义了 IP 地址结构sockaddr_in
等。string.h
:提供字符串处理函数的定义。arpa/inet.h
:提供了一些 IP 地址转换函数的定义。unistd.h
:提供了一些系统调用函数的定义。pthread.h
:提供了多线程支持的函数定义。stdlib.h
:标准库函数定义。
-
在
main
函数中:-
创建一个 UDP 套接字:
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
。- 使用
socket
函数创建一个基于 IPv4 的 UDP 套接字。 - 如果创建失败,会输出错误信息并返回。
- 使用
-
定义并初始化发送者的地址结构体
my_addr
,并将套接字绑定到该地址:struct sockaddr_in my_addr; memset(&my_addr, 0, sizeof(my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(9000); my_addr.sin_addr.s_addr = htonl(INADDR_ANY); int ret = bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
- 如果绑定失败,会输出错误信息并返回。
-
定义并初始化接收者的地址结构体
dst_addr
,并设置目标 IP 地址和端口:struct sockaddr_in dst_addr; memset(&dst_addr, 0, sizeof(dst_addr)); dst_addr.sin_family = AF_INET; dst_addr.sin_port = htons(8000); inet_pton(AF_INET, "192.168.31.37", &dst_addr.sin_addr.s_addr);
- 将目标 IP 地址转换为网络字节序。
-
发送数据给接收者:
char buf[] = "你好,大帅逼"; sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&dst_addr, sizeof(dst_addr));
-
关闭套接字:
close(sockfd);
-
-
总结:
- 该程序创建了一个 UDP 套接字,将发送者的地址绑定到端口 9000,并向 IP 地址为 "192.168.31.37"、端口为 8000 的目标发送了数据 "你好,大帅逼"。
- 这段代码是一个简单的 UDP 客户端程序,实现了向指定目标发送数据的功能。