目录
struct sockaddr & struct scokaddr_in
是32位网络字节序IP地址和点分十进制的IP地址互相转换的函数
补充:memset(buf,0,sizeof(buf)) inet_ntop(pHost->h_addrtype,pHost->h_addr_list[i],buf,sizeof(buf))
01:根据域名,获取一下知名互联网厂商的IP地址信息,如阿里、京东、腾讯、百度。
02:先简单说说socket、bind、listen、accept、connect函数分别有什么基本作用呢?
04:编写两个程序,一个是客户端另一个是服务端,它们通过tcp连接进行即时聊天
scp xiaohuichen@192.168.235.128:/home/xiaohuichen/homework/嘘月.mp3 F:\WANGDAO1\讲义\LNIUX
天使!!!!天使!!!天使!!!万万是天使!!!!!他是天使!!!!!!
补:抓包(抓不了一点喵)
根本不知道他讲了什么喵,他们两个有什么区别喵
这是三次挥手吗喵
这是四次挥手吗喵
LINUX抓包-不懂反正多了个包
netstat -ano| grep tcp
netstat -a |grep tcp (所以那个no是什么)
ifconfig -a
sudo tcpdump -i ens33 -S -w txt.cap (-w 写进文件喵)
01:地址信息设置
struct sockaddr & struct scokaddr_in
//是一个通用的结构体,用来表示各种类型的 socket 地址
/*通用的结果是直接用它
来描述一个具体的IP地址和端口号十分困难。所以用户一般
先使用 struct sockaddr_in 来构造地址,
再将其进行强制类型转换成 struct sockaddr 以作为网络接口的参数*/
struct sockaddr {
unsigned short sa_family; // 地址族(Address Family),如 AF_INET、AF_INET6 等
char sa_data[14]; // 存放 socket 地址的具体内容,包括 IP 地址和端口号
};
//struct sockaddr_in 是用来存储 IPv4 地址的结构体,是 struct sockaddr 的一个具体实现。
struct sockaddr_in {
short sin_family; // 地址族,通常设置为 AF_INET
unsigned short sin_port; // 16 位端口号,网络字节序(big-endian)
struct in_addr sin_addr; // IPv4 地址结构体
char sin_zero[8]; // 填充字段,通常设置为 0
};
在网络编程中,地址族(Address Family)是一个标识,用于指示套接字(socket)地址结构中包含的是什么类型的地址。不同的地址族对应不同的网络协议或者地址类型
大小端转换
大小端转换函数
#inlcude <arpa/inet.h>
//horst long(32)-->network long
unit32_t htol(unit_32 hostlong);
//horst short(16)-->network short
unit32_t htos(unit_16 hostshort);
//network long-->horst long
unit32_t ntohl(unit_32 netlong);
//network short-->horst short
unit32_t ntohs(unit_16 netshort);
是32位网络字节序IP地址和点分十进制的IP地址互相转换的函数
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char* cp,struct in_addr *inp)
char* inet_ntoa(struct in_addr in);
线程安全版本是inet_atop inet_ptoa
//cp:指向以字符串形式表示的 IP 地址的指针,例如 "192.168.1.1"。
//inp:指向 struct in_addr 结构的指针,用于存储转换后的二进制 IP 地址。
示例
#include <func.h>
int main(int argc,char* argv[])
{
//host short
unsigned short us=0x123;
printf("%x\n",us);
//host short-->network short
unsigned short us1=htons(us);
printf("%x\n",us1); //2301???不是网络大端吗喵
//ns-->hs
printf("%x\n",ntohs(us1));
printf("__________\n");
//./inet_aton 127.0.0.1
struct sockaddr_in addr;
//.10-->32nl
inet_aton(argv[1],&addr.sin_addr);
printf("addr=%x\n",addr.sin_addr.s_addr);
//32nl-->.10
printf("addr=%s\n",inet_ntoa(addr.sin_addr));
return 0;
}
123
2301 (network short不是大端吗喵?)
123
__________
addr=100007f
addr=127.0.0.1
域名和IP地址的对应关系
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
}
/*函数声明 struct hostent *gethostbyname(const char *name);
这个函数用于通过主机名获取主机的信息,包括主机的正式名称、别名列表、地址类型、地址长度以及地址列表。
参数:
name:要查询的主机名,以字符串形式传入。
返回值:
如果成功,返回一个指向 struct hostent 结构体的指针。
如果失败,返回 NULL,并且可以通过全局变量 h_errno 查看错误码,例如 HOST_NOT_FOUND 或 NO_DATA。
结构体 struct hostent
这个结构体定义了主机的信息,包含以下成员:
char *h_name:主机的官方名称。
char **h_aliases:主机的别名列表,以 NULL 结尾的字符串数组。
int h_addrtype:主机地址类型,通常是 AF_INET 表示 IPv4 地址。
int h_length:地址的长度,通常是 IPv4 地址的字节长度(4)。
char **h_addr_list:主机的地址列表,以网络字节序的二进制形式表示,可以通过这个列表获取主机的各个 IP 地址。*/
示例
#include <func.h>
int main(int argc,char* argv[])
{
if(argc!=2){error(1,0,"usage %s daa",argv[1]);}
//h_name get h_massge
struct hostent*pHost=gethostbyname(argv[1]);
if(!pHost){error(1,errno,"gethostbyname");}
printf("h_name=%s\n",pHost->h_name);//h_name
//each aliases
for(int i=0;pHost->h_aliases[i]!=NULL;i++){
printf("h_aliases[%d]=%s\n",i,pHost->h_aliases[i]);
}
//type
printf("addrtype=%d\n",pHost->h_addrtype);
//len
printf("addrlen=%d\n",pHost->h_length);
char buf[128]={0};
//主机的地址列表 char** h_addr_list
for(int i=0;pHost->h_addr_list[i]!=NULL;i++){
memset(buf,0,sizeof(buf));
inet_ntop(pHost->h_addrtype,pHost->h_addr_list[i],buf,sizeof(buf));
printf("addr=%s\n",buf);
}
return 0;
}
补充:memset(buf,0,sizeof(buf))
inet_ntop(pHost->h_addrtype,pHost->h_addr_list[i],buf,sizeof(buf))
void *memset(void *ptr, int value, size_t num);
内存区域起始地址,要设置的值,要设置的字节数
inet_ntop(pHost->h_addrtype,pHost->h_addr_list[i],buf,sizeof(buf))
将网络字节序的地址转换为一个以点分十进制表示的字符串格式
(地址族,要转换的地址,转换后地址存贮的地方,dst的大小-避免溢出)
02:TCP通信
流程
sock() 创建一个SOCKET设备
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
//domain AF_INET --> IPv4 AF_INET6 --> IPv6 通信的协议域
//type SOCK_STREAM --> TCP SOCK_DGRAM --> UDP 套接字类型
//protocol IPPROTO_TCP --> TCP IPPROTO_UDP -->UDP 协议类型
connect() 建立和TCP服务端的连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//socket返回的套接字描述符(文件描述符) 指向struct sockaddr的指针 addr结构体长度
//0 -1/errno
IP地址的转换
const char* ip="192.168.30.129"
int inet_aton(const char*cp ,struct in_addr *inp);
//将一个点分十进制的 IP 地址转换为网络字节序的二进制格式,并存储在 struct in_addr 结构体的 inp 参数中
//return 非0 0
in_addr_t inet_addr(const char*cp);
//将一个点分十进制的 IP 地址转换为网络字节序的二进制格式
//函数返回一个 in_addr_t 类型的值,即网络字节序的 IP 地址。如果转换失败,返回 INADDR_NONE。
struct in_addr{ unit32_t s_addr; } //4字节的整型数据
//是用来存储 IPv4 地址的数据结构
//network -->./
char* inet_ntoa(struct in_addr in);
const char*inet_ntop(int af,//地址族,通用形式,IPV4,IPV6
const void* src, //网络字节序的IP地址
char* dst, //可视化的IP地址,传出参数,用来存储转换后的点分十进制字符串的缓冲区
socklen_t size); //函数返回一个指向转换后的点分十进制字符串的指针,如果发生错误,则返回 NULL
//C语言中传递一个数组的方式是首地址+长度
//函数执行通用的网络地址到主机地址的转换
示例
#include <func.h>
int main(int argc ,char* argv[])
{
if(argc!=3){error(1,0,"usage %s dada","argv[1]");}
//第一个参数是服务器的 IP 地址,可以是一个有效的 IPv4 地址。
//第二个参数是服务器监听的端口号,通常是一个整数值,表示端口号范围在 0 到 65535 之间。
//socket 存储服务器的地址信息
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1){error(1,errno,"socket");}
struct sockaddr_in serAddr;
memset(&serAddr,0,sizeof(serAddr));
serAddr.sin_family=AF_INET; //指定地址族
serAddr.sin_addr.s_addr=inet_addr(argv[1]);//if INADDR_ANY,表示选择本机IP地址
//命令行参数 argv[1] 中的 IP 地址转换为网络字节序
//inet_addr 函数用于将点分十进制 IP 地址转换为 in_addr_t 类型(二进制)
serAddr.sin_port=htons(atoi(argv[2]));
//命令行参数 argv[2] 中的端口号转换为整数后,使用 htons 函数将端口号转换为网络字节序,并存储在 //sin_port 中
int ret =bind (sfd,(struct sockaddr*)&serAddr,sizeof(serAddr));
if(ret==-1){error(1,errno,"bind");}
//使用 bind 函数将创建的套接字 sfd 绑定到 serAddr 所指定的地址和端口
return 0;
}
作业:
01:根据域名,获取一下知名互联网厂商的IP地址信息,如阿里、京东、腾讯、百度。
见域名和地址的对应关系喵~好耶~做出一题喵
h_name=xiaomiipv6.v.bsgslb.cn
h_aliases[0]=www.mi.com
h_aliases[1]=www.mi.com.mgslb.com
h_aliases[2]=www.mi.com.bsgslb.cn
addrtype=2
addrlen=4
addr=115.152.252.67
addr=115.152.252.64
addr=111.180.203.45
addr=111.180.203.46
addr=111.180.203.61
addr=111.180.203.62