D8 - 网络编程扩展

  • 每次复制代码时,如果代码里有 // 这样的注释就容易让格式乱掉 >>>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 *   创建日期:202007287 *   描    述:
  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
*   创建日期:20200728*   描    述:
*	通过代码获取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
*   创建日期:20200728*   描    述:
*	通过代码获取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协议。有专门的组播地址
  • [ ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值