- 每次复制代码时,如果代码里有 // 这样的注释就容易让格式乱掉 >>>set paste后再粘贴即可
第一节 网络信息检索
1.1 gethostbyname函数
struct hostent *gethostbyname(const char *hostname); |
---|
功能:获取主机host的IP地址通过域名name (由于服务器的域名是不会变的,服务器的IP是变化的,通过该方式可以获取IP地址) |
参数 : 域名 |
返回值: hostent 结构体 struct hostent{ char *h_name;//official name官方域名 char **h_aliases; //alias list别名 int h_addrtype;//host address type,IPv4还是IPv6 int h_length;//address lenght保存IP地址长度 char **h_addr_list; //address list,IP地址(网络地址,如果用户需要查看,需要用inet_ntop转成点分十进制的地址) } |
使用gethostbuname查看www.baidu.com的IP地址,并用点分十进制显示出来
1 ===============================================================
2 * Copyright (C) 2020 All rights reserved.
3 *
4 * 文件名称:text1.c
5 * 创 建 者:liujing
6 * 创建日期:2020年07月28日
7 * 描 述:
8 * 通过代码获取www.baidu.com的IP地址
9 * 更新日志:
10 *
11 ================================================================*/
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <strings.h>
16 #include <netdb.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 void main()
21 {
22 //定义结构体指针来接收host的IP信息
23 struct hostent*Hostent;
24
25 Hostent = gethostbyname("www.baidu.com");
26
27 printf("\n官方域名:%s\n",Hostent->h_name);
28 printf("\n别名:%s\n",*Hostent->h_aliases);
29 printf("\n类型:%d\n",Hostent->h_addrtype);
30 printf("\nIP长度:%d\n",Hostent->h_length);
31
32 char str[32];
33 //将网络地址-->点分十进制地址存储在str
34 inet_ntop(Hostent->h_addrtype,*Hostent->h_addr_list,str,32);
35 printf("\nIP地址:%s\n",str);
36
37 }
================================================================*
运行结果与IP验证:
farsight@ubuntu:~/Desktop$ ./a.out
官方域名:www.a.shifen.com
别名:www.baidu.com
类型:2
IP长度:4
IP地址:61.135.169.121
farsight@ubuntu:~/Desktop$ ping www.baidu.com
PING www.a.shifen.com (61.135.169.125) 56(84) bytes of data.
64 bytes from 61.135.169.125: icmp_req=1 ttl=54 time=40.8 ms
64 bytes from 61.135.169.125: icmp_req=2 ttl=54 time=42.4 ms
64 bytes from 61.135.169.125: icmp_req=3 ttl=54 time=49.9 ms
==>成功
================================================================*
第二节 网络属性设置(了解)
2.1 setsockopt
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); |
---|
参数1:sockfd是被修改的socket描述符 |
参数2 :level:需要修改哪一类套接字 SOL_SOCKET: 基本套接口 IPPROTO_IP: IPv4套接口 IPPROTO_IPV6: IPv6套接口 IPPROTO_TCP: TCP套接口 |
参数3:你要修改的那个属性 |
参数4:optval是重新写入的属性的值 |
参数5:optlen代表重新写入的属性的值的大小 |
第三节 超时检查
- 避免进程在没有数据时无限制地阻塞
3.1 使用setsockopt实现网络超时检测
- 设置一次,永久有效。对所有和网络相关的阻塞函数有效
- 当使用accept/recvfrom这类阻塞函数时,会自动设置最大阻塞休眠时间为我们setsockopt设置的超时时间
struct timeval time_out;
time_out.tv_sec=5;
time_out.tv_usec=0;
//SO_RCVTIMEO 设置接收超时时间
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(time_out)) < 0)
{
perror("fail to setsockopt");
}
==>
TCP套接字中的recv/accept
UDP套接字中的recvfrom
3.2 使用select函数实现网络超时检测
- int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);可以设置最大select时间,来判断socket网络是否超时
3.3 使用alarm闹钟实现网络超时检测
- 当闹钟响时,会触发SIGALRM信号,执行信号处理函数,当信号处理函数执行完毕,会接着刚才的代码继续执行
第四节 广播 //UDP编程
-
同时发给局域网中的所有主机,称为广播;
-
只有UDP协议套接字才能广播
广播编程注意 { 接收端 1:UDP套接字 2:修改UDP套接字的属性 3:bind //接收端地址=广播地址;广播地址与本机IP都可以bind 4:recvfrom接收 发送端: 1:UDP套接字 2:修改UDP套接字的属性 4:sendto发送 }
发送端与接收端通过广播地址进行广播通信
接收端代码:
===============================================================
* Copyright (C) 2020 All rights reserved.
*
* 文件名称:ser.c
* 创 建 者:liujing
* 创建日期:2020年07月28日
* 描 述:
* 通过代码获取www.baidu.com的IP地址
* 更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void main()
{
printf("\nsocket success\n");
//创建UDP的套接字
int socket_fd;
socket_fd =socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd == -1)
{
perror("\nsocket error\n");
}
else
{
printf("\nsocket success\n");
}
//设置UDP的套结字为广播类型
//基本套结字+允许套结字传送广播信息+(1=允许)
int value = 1; //允许
if(-1 == setsockopt(socket_fd,SOL_SOCKET,SO_BROADCAST,(const void *)&value,(socklen_t)sizeof(value)))
{
perror("\nsetsockopt error\n");
}
else
{
printf("\nsetsockopt success\n");
}
//bind服务器的网络地址
struct sockaddr_in addrto;
addrto.sin_family=AF_INET;
//由于服务器处于192.168.43网段,服务器作为UDP的接受方,服务器的IP绑定为广播地址
//接受方的地址=广播地址
inet_pton(AF_INET,"192.168.43.255",&addrto.sin_addr.s_addr);
addrto.sin_port=5001;
int nlen=sizeof(addrto);
if(-1 == bind(socket_fd,(const struct sockaddr *)&addrto,nlen))
{
perror("bind error");
}
else
{
printf("bind success");
}
//UDP发送
while(1)
{
char str[32] = "hello word";
//接收
if(recvfrom(socket_fd,str,32,0,(struct sockaddr *)&addrto, &nlen) < 0)
{
perror("\nsendto error\n");
}
else
{
printf("\nget %s\n",str);
}
sleep(2);
}
}
发送端代码:
===============================================================
* Copyright (C) 2020 All rights reserved.
*
* 文件名称:cli.c
* 创 建 者:liujing
* 创建日期:2020年07月28日
* 描 述:
* 通过代码获取www.baidu.com的IP地址
* 更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void main()
{
printf("\nsocket success\n");
//创建UDP的套接字
int socket_fd;
socket_fd =socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd == -1)
{
perror("\nsocket error\n");
}
else
{
printf("\nsocket success\n");
}
//设置UDP的套结字为广播类型
//基本套结字+允许套结字传送广播信息+(1=允许)
int value = 1; //允许
if(-1 == setsockopt(socket_fd,SOL_SOCKET,SO_BROADCAST,(const void *)&value,(socklen_t)sizeof(value)))
{
perror("\nsetsockopt error\n");
}
else
{
printf("\nsetsockopt success\n");
}
//bind服务器的网络地址
struct sockaddr_in addrto;
addrto.sin_family=AF_INET;
inet_pton(AF_INET,"192.168.43.255",&addrto.sin_addr.s_addr);
addrto.sin_port=5001;
int nlen=sizeof(addrto);
//UDP发送
while(1)
{
char str[32] = "hello word";
//发送
if(sendto(socket_fd,str,32,0,(struct sockaddr *)&addrto, nlen) < 0)
{
perror("\nsendto error\n");
}
else
{
printf("\nsend %s\n",str);
}
sleep(2);
}
}
================================================================
发送端运行如下
farsight@ubuntu:~/Desktop$ ./cli
socket success
socket success
setsockopt success
send hello word
send hello word
send hello word
send hello word
send hello word
send hello word
================================================================
接收端运行如下:
farsight@ubuntu:~/Desktop$ ./ser
socket success
socket success
setsockopt success
bind success
get hello word
get hello word
get hello word
get hello word
get hello word
get hello word
================================================================
第五节 组播 //UDP
- 广播的时候,接收端必须调用bind函数指定接收端的端口号,显示的指定自己用的端口号
- 组播,必须使用UDP协议。有专门的组播地址
- [ ]