[Linux]网络基础 part2 :套接字编程

文章目录

  • 字节序
  • 套接字编程
  • 客户端与服务端
  • ★ netstat命令 ★
  • UDP通信程序
    • 通信流程:
    • 接口:
    • 流程外的重要接口:
  • TCP通信程序
    • 通信流程:

字节序

字节序:cpu对内存中数据进行存取的顺序

主机字节序的分类:小端、大端

小端:低地址存低位
大端:低地址存高位

[Linux]网络基础 part2 :套接字编程_第1张图片
编写代码判断主机字节序:

#include
using namespace std;
void check_sys1()
{
     
	int a = 1;
	char* b = (char*)&a;
	if (*b == 1)
		cout << "小端" << endl;
	if (*b == 0)
		cout << "大端" << endl;
}
void check_sys2()
{
     
	//联合类型的所有数据共用一块内存,内存大小根据最大的数据类型决定
	union UN {
     
		int a;
		char b;
	}u;
	u.a = 1;
	if(u.b==1)
		cout << "小端" << endl;
	if(u.b==0)
		cout << "大端" << endl;
}
int main()
{
     
	check_sys1();
	check_sys2();
	return 0;
}

[Linux]网络基础 part2 :套接字编程_第2张图片

主机字节序对网络通信的影响:如果通信两端主机字节序不同,可能会造成数据二义性。

解决方案:订立网络通信字节序标准,规定网络中的数据都按照网络字节序进行存取。网络字节序-----其实是大端字节序

发送方将数据转换成网络字节序后进行发送,接收方根据自己的的主机字节序将接收到的数据进行转换。

字节序只针对存储单元大于一个字节的数据类型。
注意:字符串实际上是单字节存储,所以不需要转换。

套接字编程

socket 套接字编程:网络通信程序的编写

分类:UDP协议通信程序的/TCP协议通信程序

区别:
UDP协议:用户数据报协议
特点:无连接,不可靠,面向数据报
应用场景:实时性要求大于安全性要求----例如视频传输

TCP协议:传输控制协议
特点:面向连接,可靠,面向字节流
应用场景:安全性要求大于实时性要求----例如文件传输

客户端与服务端

在网络通信程序中,通信两端被分为客户端和服务端,
客户端:提供给客户的通信段,通常是通信程序中主动发起请求的一端。
客户端必须提前知道服务端的地址信息(ip地址+port端口)才能发送请求,通常是被提前写在应用程序中,并且通常是固定不变的。

服务端:通常是指被动接受请求,提供服务的通信端。
[Linux]网络基础 part2 :套接字编程_第3张图片

★ netstat命令 ★

netstat命令:查看当前网络状态信息
-a:查看所有
-t :查看TCP信息
-u:查看UDP信息
-n:不宜服务名称显示
-p:查看当前网络状态对应的进程

UDP通信程序

通信流程:

[Linux]网络基础 part2 :套接字编程_第4张图片

接口:

1、创建套接字:int socket(int domain,int type,int protocol);

domain:地址域类型----指定使用的是什么样的地址结构:AF_INET----IPV4通信,使用IPV4地址结构
type:套接字类型;SOCK_STREAM:流式套接字 / SOCK_DGRAM:数据报套接字

注意:TCP协议必须使用SOCK_STREAM,UDP必须使用SOCK_DGRAM

protocol:本次通信所使用的协议;IPPROTO_IP=6 / IPPROTO_UDP=17(可以使用宏,也可以使用数字)
返回值:成功,返回一个文件描述符----操作句柄;失败,返回-1。

2、为套接字绑定地址信息:int bind(int sockfd,struct sockaddr* addr,socklen_t addrlen);

sockfd:socket() 创建套接字返回的操作句柄
addr:当前绑定的地址信息
socklen_t addrlen:地址信息长度
返回值:成功返回0;失败返回-1。

3、接收数据:ssize_t recvfrom(int sockfd,void* buf,int len,int flag,struct addr* srcaddr,socklen_t * addrlen);

ssize_t:有符号int;
size_t:无符号int

sockfd:创建套接字返回的操作句柄
buf:用于存放接收到的数据的空间地址
len:需要接受的数据长度
flag:选项标志,通常默认为0,表示阻塞接收
srcaddr:本条数据的源端地址信息
addrlen:输入输出参数,指定要接收多长的地址长度,但实际可能并没有那么长,所以还会返回实际接收到的地址长度
返回值:成功,返回实际接收到的数据长度;失败或出错返回-1。

4、发送数据:ssize_t sendto(int sockfd,void *data,int len,int flag,struct sockaddr* peeraddr,socklen_t addrlen);

sockfd:操作句柄
data:要发送的数据的首地址
len:要发送的数据长度
flag:默认为0,阻塞发送
peeraddr:对端地址信息
addrlen:地址结构长度
返回值:成功,返回实际发送的数据长度;失败,返回-1。

5、关闭套接字:int close(int fd);

fd:操作句柄

流程外的重要接口:

字节序转换接口:

unint32_t htonl(uint32_t hostlong);----32位数据主机字节序到网络字节序的转换
unint16_t htons(uint32_t hostshort);----16位数据主机字节序到网络字节序的转换
unint32_t ntohl(uint32_t netlong);----32位数据网络字节序到主机字节序的转换
unint16_t ntohs(uint32_t netshort);----16位数据网络字节序到主机字节序的转换
注意:port端口转换使用htons/ntohs,ip转换使用htonl/ntohl,不能混用。

将字符串点分十进制IP地址转换为整型网络字节序IP地址:

“192.168.2.2”————》0xc0a80202
in_addr_t inet_addr(const char* cp);

将网络字节序IP地址转换为字符串点分十进制IP地址:

0xc0a80202————》“192.168.2.2”
char* inet_ntoa(struct in_addr in);

以上接口仅限于IPV4地址使用

不限于IPV4的地址转换:

int inet_pton(int af,const char* src,void* dst);
const char* inet_ntop(int af,void* src,char* dst,socklen_t size);
(1)这两个函数的af参数既可以是AF_INET(ipv4)也可以是AF_INET6(ipv6)。如果,以不被支持的地址族作为af参数,这两个函数都返回一个错误,并将errno置为EAFNOSUPPORT.
(2)第一个函数尝试转换由src指针所指向的字符串,并通过dst指针存放二进制结果,若成功则返回值为1,否则如果所指定的af而言输入字符串不是有效的表达式格式,那么返回值为0.
(3)inet_ntop进行相反的转换,从数值格式(src)转换到表达式(dst)。inet_ntop函数的src参数不可以是一个空指针。调用者必须为目标存储单元分配内存并指定其大小,调用成功时,这个指针就是该函数的返回值。size参数是目标存储单元的大小,以免该函数溢出其调用者的缓冲区。如果size太小,不足以容纳表达式结果,那么返回一个空指针,并置为errno为ENOSPC。

TCP通信程序

通信流程:

[Linux]网络基础 part2 :套接字编程_第5张图片

你可能感兴趣的:(Linux,网络,socket)