Home Article Practice 11_udp

11_udp

2024-05-09 14:25  views:204  source:拼搏百天我要上蓝翔    

知识点1【字节序】将多字节看成一个整体存储的顺序。字节序分为:大端格式、小端格式。大小端是系统决定的,我们不能
更改。案例1:判断当前系统是大端还是小端只需要判断低地址 存放的是高字节 还是低字节。知识点1【网络字节序和主
机字节序】1、如果计算机没有考虑字节序的问题,导致传输的数据错误2、解决上述问题网络中的数据 必须是大端。发送
数据:需要将 主机字节序 转 网络字节序 hton接收数据:需要将 网络字节序 转 主机字节序 ntoh知识点
2【字节序的转换函数】1 #include <arpa/inet。h>1、主机字节序 转 网络字节序(发送数据
)1 uint32_t htonl(uint32_t hostint32);//转IP2 uint16_t h
tons(uint16_t hostint16);//转端口号2、网络字节序 转 主机字节序(接收数据)1 u
int32_t ntohl(uint32_t netint32);//转IP2 uint16_t ntohs(
uint16_t netint16);//转端口案例1:使用以htons htonl知识点3【地址转换函数】"
10。9。11。3" 点分十进制数串 (用户识别的IP地址)但是:计算机 是用32位无符号数据 存储IP地址1
、发送数据 将点分十进制数据 转换成 32为无符号数据1 #include <arpa/inet。h>1 in
t inet_pton(int family,const char *strptr, void *addrpt
r);2 功能:3 将点分十进制数串转换成32位无符号整数4 参数:5 family 协议族 AF_INET‐
‐>IPv4 AF_INET6‐‐>IPv66 strptr 点分十进制数串7 addrptr 32位无符号整
数的地址8 返回值:9 成功返回1 、 失败返回其它案例1:将"10。9。11。3"转换成32位无符号数据2、
接收数据 将32为无符号数据 转换成 点分十进制数串1 const char *inet_ntop(int f
amily, const void *addrptr,2 char *strptr, size_t len)3
功能:4 将32位无符号整数转换成点分十进制数串5 参数:6 family 协议族 AF_INET7 add
rptr 32位无符号整数8 strptr 点分十进制数串9 len strptr缓存区长度10 len的宏定
义11 #define INET_ADDRSTRLEN 16 //for ipv412 #define INE
T6_ADDRSTRLEN 46 //for ipv613 返回值:14 成功:则返回字符串的首地址15 失败
:返回NULL案例1:将32为无符号数据 转换成 点分十进制数串知识点4【UDP编程概述】1、socket网络
通信的3要素:IP、PORT、协议socket 他是网络编程接口的统称。socket 他是通信的一个端点(IP
、PORT信息),是特殊的文件描述符(套接字)。2、udp的编程流程3、socket函数创建一个套接字(通信的
端点)1 #include <sys/socket。h>2 int socket(int family,int
type,int protocol);3 功能:4 创建一个用于网络通信的socket套接字(描述符)5 参
数:6 family:协议族(AF_INET、AF_INET6、PF_PACKET等)7 type:套接字类(
SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)8 protocol:协议类别(0、IPPR
OTO_TCP、IPPROTO_UDP等910 返回值:11 套接字12 特点:13 创建套接字时,系统不会分
配端口4、IPv4地址结构体定义 地址结构体变量1 #include <netinet/in。h>1 stru
ct in_addr2 {3 in_addr_t s_addr;//4字节4 };5 struct socka
ddr_in //IPv4地址结构体6 {7 sa_family_t sin_family;//2字节 AF_
INET AF_INET68 in_port_t sin_port;//2字节9 struct in_addr
sin_addr;//4字节10 char sin_zero[8]//8字节11 };5、通用套接字地址结构
对传递给函数的实参进行类型转换 不做赋值操作1 struct sockaddr2 {3 sa_family_t
sa_family; // 2字节4 char sa_data[14] //14字节5 };6、sendto
发送udp消息1 ssize_t sendto(int sockfd,const void *buf,size
_t nbytes,int flags,2 const struct sockaddr *to, sockle
n_t addrlen);3 功能:4 向to结构体指针中指定的ip,发送UDP数据5 参数:6 sockfd
:套接字7 buf: 发送数据缓冲区8 nbytes: 发送数据缓冲区的大小910 flags:一般为011
to: 指向目的主机地址结构体的指针12 addrlen:to所指向内容的长度13 注意:14 通过to和ad
drlen确定目的地址15 可以发送0长度的UDP数据包16 返回值:17 成功:发送数据的字符数18 失败:
‐1案例1:发送消息1 #include <stdio。h>2 #include <sys/socket。h
> //socket3 #include <unistd。h> //close4 #include <stri
ng。h> //memset strlen5 #include <netinet/in。h> //struct
sockaddr_in6 #include <arpa/inet。h> //inet_pton7 int m
ain(int argc, char const *argv[])8 {9 //创建用于通信的udp套接字10
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);11 if (soc
kfd < 0)12 {13 perror("socket");14 return 0;15 }16 prin
tf("sockfd = %d\n", sockfd);1718 //发送数据 sendto19 char b
uf[] = "hello sockfd";20 //目的地址信息21 struct sockaddr_in
dst_addr;22 memset(&dst_addr, 0, sizeof(dst_addr));23 d
st_addr。sin_family = AF_INET; //IPv424 dst_addr。sin_por
t = htons(8000); //端口25 //将目的IP 赋值到地址结构体中26 inet_pton(A
F_INET, "10。9。11。251", &dst_addr。sin_addr。s_addr);2728
//如果套接字 没有事先bind绑定固定的IP以及端口29 //那么第一次调用sendto的时候系统会给本地主
机IP,以及随机端口,作为源地址信息30 sendto(sockfd, buf, strlen(buf), 0
, (struct sockaddr *)&dst_addr, sizeof(dst_addr));3132
char buf1[] = "hello buf1";33 sendto(sockfd, buf1, strl
en(buf1), 0, (struct sockaddr *)&dst_addr, sizeof(dst_a
ddr));3435 close(sockfd);3637 return 0;38 }7、bind给套接字绑定
固定的IP和端口bind只能绑定本地机的IP地址1 创建套接字2 bind固定IP以及端口3 sendto发送
数据或recvfrom接收数据1 int bind(int sockfd,const struct socka
ddr *myaddr,socklen_t addrlen);2 功能:3 将本地协议地址与sockfd绑定4
参数:5 sockfd: socket套接字6 myaddr: 指向特定协议的地址结构指针7 addrlen
:该地址结构的长度8 返回值:9 成功:返回010 失败:其他1 #include <stdio。h>2 #i
nclude <sys/socket。h> //socket3 #include <unistd。h> //c
lose4 #include <string。h> //memset strlen5 #include <ne
tinet/in。h> //struct sockaddr_in6 #include <arpa/inet。h
> //inet_pton7 int main(int argc, char const *argv[])8
{9 //创建用于通信的udp套接字10 int sockfd = socket(AF_INET, SOCK_
DGRAM, 0);11 if (sockfd < 0)12 {13 perror("socket");14
return 0;15 }16 printf("sockfd = %d\n", sockfd);1718 //
bind固定的IP以及端口19 struct sockaddr_in my_addr;20 memset(&m
y_addr, 0, sizeof(my_addr));21 my_addr。sin_family = AF_
INET;22 my_addr。sin_port = htons(9000); //源端口23 my_addr
。sin_addr。s_addr = htonl(INADDR_ANY); //通配地址24 int ret
= bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_a
ddr));25 if (ret < 0)26 {27 perror("bind");28 return 0;
29 }3031 //发送数据 sendto32 char buf[] = "hello sockfd";33
//目的地址信息34 struct sockaddr_in dst_addr;35 memset(&dst_
addr, 0, sizeof(dst_addr));36 dst_addr。sin_family = AF_
INET; //IPv437 dst_addr。sin_port = htons(8000); //目的端口3
8 //将目的IP 赋值到地址结构体中39 inet_pton(AF_INET, "10。9。11。251",
&dst_addr。sin_addr。s_addr);4041 //如果套接字 没有事先bind绑定固定的I
P以及端口42 //那么第一次调用sendto的时候系统会给本地主机IP,以及随机端口,作为源地址信息43 s
endto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&
dst_addr, sizeof(dst_addr));4445 char buf1[] = "hello b
uf1";46 sendto(sockfd, buf1, strlen(buf1), 0, (struct s
ockaddr *)&dst_addr, sizeof(dst_addr));4748 close(sockf
d);4950 return 0;51 }528、recvfrom接收数据(阻塞)如果只负责收数据 记得事先b
ind固定的端口以及IP1 ssize_t recvfrom(int sockfd, void *buf,si
ze_t nbytes,int flags,2 struct sockaddr *from,socklen_t
*addrlen);3 功能:4 接收UDP数据,并将源地址信息保存在from指向的结构中5 参数:6 so
ckfd: 套接字7 buf:接收数据缓冲区8 nbytes:接收数据缓冲区的大小9 flags: 套接字标志
(常为0)10 from: 源地址结构体指针,用来保存数据的来源11 addrlen: from所指内容的长度
12 注意:13 通过from和addrlen参数存放数据来源信息14 from和addrlen可以为NULL
, 表示不保存数据来源15 返回值:16 成功:接收到的字符数17 失败: ‐11 #include <std
io。h>2 #include <sys/socket。h> //socket3 #include <unis
td。h> //close4 #include <string。h> //memset strlen5 #in
clude <netinet/in。h> //struct sockaddr_in6 #include <ar
pa/inet。h> //inet_pton7 int main(int argc, char const *
argv[])8 {9 //创建用于通信的udp套接字10 int sockfd = socket(AF_IN
ET, SOCK_DGRAM, 0);11 if (sockfd < 0)12 {13 perror("soc
ket");14 return 0;15 }16 printf("sockfd = %d\n", sockfd
);1718 //bind固定的IP以及端口19 struct sockaddr_in my_addr;20
memset(&my_addr, 0, sizeof(my_addr));21 my_addr。sin_fam
ily = AF_INET;22 my_addr。sin_port = htons(8000); //源端口2
3 my_addr。sin_addr。s_addr = htonl(INADDR_ANY); //通配地址24
int ret = bind(sockfd, (struct sockaddr *)&my_addr, si
zeof(my_addr));25 if (ret < 0)26 {27 perror("bind");28
return 0;29 }3031 //recvfrom接收数据32 while (1)33 {34 unsi
gned char buf[1500] = "";35 struct sockaddr_in from_add
r;36 socklen_t from_len = sizeof(from_addr);3738 int le
n = recvfrom(sockfd, buf, sizeof(buf), 0,39 (struct soc
kaddr *)&from_addr, &from_len);40 if (len < 0)41 {42 pe
rror("recvfrom");43 return 0;44 }45 //获取发送者的IP46 char i
p_str[16] = "";47 inet_ntop(AF_INET, &from_addr。sin_add
r。s_addr, ip_str, 16);48 //获取发送者的端口49 unsigned short po
rt = ntohs(from_addr。sin_port);5051 printf("IP:%s PORT:
%hu 长度:%d 消息:%s\n", ip_str, port, len, buf);52 }53 clos
e(sockfd);5455 return 0;56 }知识点5【UDP_QQ聊天程序】1 #include
<stdio。h>2 #include <sys/socket。h> //socket3 #include <
unistd。h> //close4 #include <string。h> //memset strlen5
#include <netinet/in。h> //struct sockaddr_in6 #include
<arpa/inet。h> //inet_pton7 #include <pthread。h>8 #incl
ude <stdlib。h>9 void *send_fun(void *arg)10 {11 struct
sockaddr_in dst_addr;12 memset(&dst_addr, 0, sizeof(dst
_addr));13 dst_addr。sin_family = AF_INET;1415 //根据用户输入
更改目的IP和端口16 int sockfd = *(int *)arg;17 while (1)18 {19
//sayto IP port20 char buf[128] = "";21 fgets(buf, siz
eof(buf), stdin);22 buf[strlen(buf) ‐ 1] = 0;2324 if (s
trncmp(buf, "sayto", 5) == 0)25 {26 char ip_str[16] = "
";27 unsigned short port = 0;28 sscanf(buf, "sayto %s %
hu", ip_str, &port);29 dst_addr。sin_port = htons(port);
30 inet_pton(AF_INET, ip_str, &dst_addr。sin_addr。s_addr
);31 continue;32 }33 else if (strncmp(buf, "quit", 4) =
= 0)34 {35 return NULL;36 }3738 sendto(sockfd, buf, str
len(buf), 0, (struct sockaddr *)&dst_addr, sizeof(dst_a
ddr));39 }4041 return NULL;42 }4344 void *recv_fun(void
*arg)45 {46 //获得数据 打印发送者的信息47 int sockfd = *(int *)arg
;48 while (1)49 {50 unsigned char buf[1500] = "";51 str
uct sockaddr_in from_addr;52 socklen_t from_len = sizeo
f(from_addr);5354 int len = recvfrom(sockfd, buf, sizeo
f(buf), 0,55 (struct sockaddr *)&from_addr, &from_len);
56 if (len < 0)57 {58 perror("recvfrom");59 return 0;60
}61 //获取发送者的IP62 char ip_str[16] = "";63 inet_ntop(AF_
INET, &from_addr。sin_addr。s_addr, ip_str, 16);64 //获取发送
者的端口65 unsigned short port = ntohs(from_addr。sin_port);
6667 printf("IP:%s PORT:%hu 长度:%d 消息:%s\n", ip_str, por
t, len, buf);68 }69 }70 int main(int argc, char const *
argv[])71 {72 if (argc != 2)73 {74 printf("。/a。out 8000
\n");75 return 0;76 }7778 //sockfd = socket()创建一个udp套接字
79 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);80 if (s
ockfd < 0)81 {82 perror("socket");83 return 0;84 }85 pr
intf("sockfd = %d\n", sockfd);8687 //bind固定端口IP88 struc
t sockaddr_in my_addr;89 memset(&my_addr, 0, sizeof(my_
addr));90 my_addr。sin_family = AF_INET;91 my_addr。sin_p
ort = htons(atoi(argv[1])); //源端口92 my_addr。sin_addr。s_
addr = htonl(INADDR_ANY); //通配地址93 int ret = bind(sockf
d, (struct sockaddr *)&my_addr, sizeof(my_addr));94 if
(ret < 0)95 {96 perror("bind");97 return 0;98 }99100 //
创建发送线程 将sockfd传递101 pthread_t tid1, tid2;102 pthread_cr
eate(&tid1, NULL, send_fun, (void *)&sockfd);103 //创建接收
线程 将sockfd传递104 pthread_create(&tid2, NULL, recv_fun, (
void *)&sockfd);105106 //等待线程结束pthread_join107 pthread_
join(tid1, NULL);108 pthread_cancel(tid2);109 pthread_j
oin(tid2, NULL);110111 //关闭套接字112 close(sockfd);113114
return 0;115 }



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)