Linux网络编程——协议(C/S模型进行通信)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

协议:

  • 一组规则。

分层模型结构:

  • OSI七层模型:物、数、网、传、会、表、应

  • TCP/IP 4层模型。网链路层/网络接口层)、网、传、应

    1. 应用层:http、 ftp、nfs、 ssh、 te1neto 。 。
    2. 传输层:TCP、UDP
    3. 网络层:IP、ICMP、IGMP
    4. 链路层:以太网帧协议、ARP
  • B/S

      优点:缓存大量数据、协议选择灵活、速度快
      缺点:安全性、跨平台、开发工作量较小
    
  • C/S

      优点安全性、跨平台、开发工作量较小
      缺点不能缓存大量数据、严格遵守http
    
  • 网络传输流程:
    数据没有封装之前是不能在网络中传递。

  • 以太网帧协议;
    ARP协议。根据Ip地址获取mac地址。
    以太网帧协议:根据mac地址完成数据包传输。

  • IP协议:

     版本:IPv4、IPv6--4位
     TTL: time to live 。设置数据包在路由节点中的跳转上限。每经过一个路由节点该值-1减为O的路由有义务将该数据包丢弃
     源IP:32位。--- 4字节          192.168.1.108 ---点分十进制  IP地址(string) ---二进制
     目的IP:32位。--- 4字节
    
    
     IP地址:可以在网络环境中唯一标识一台主机。
     端口号:可以网络的一台主机上唯一标识一个进程。
     ip地址+端口号。可以在网络环境中唯一标识一个进程。
    
  • UDP:
    16位。源端口号。 2^~16= 65536
    16位:目的端口号。

  • TCP协议:
    16位: 源端口号。 2^16 = 65536
    16位: 目的端口号。
    32序号:
    32确认序号。
    6个标志位。
    16位窗口大小。 2^16 = 65536

网络字节序:

  • 小端法:(pc本地存储)高位存高地址。地位存低地址。 int a = 0x12345678

  • 大端法:网络存储高位存低地址。地位存高地址。

     htonl -->本地-->网络(IP)       
     		192.168.1.11 --> string --> atoi --> int --> htonl --〉网络字节序
     htons -->本地--》网络(port)      
     ntohl -->网络--》本地IP)
     ntohs -->网络--》本地Port)
    

IP地址转换函数:

  • int inet_pton(int afconst char *srcvoid *dst) ;
    af: AF_INET、AF_INET6
    src:传入IP地址(点分十进制)
    dst:传出转换后的网络字节序的IP地址。
    返回值:成功:1异常:0说明src指向的不是一个有效的ip地址。失败:-1
  • const char *inet_ntop(int afconst void *srcchar *dstsocklen_t
    size); 网络字节序—〉本地字节序(string IP)
    af: AF_INET、AF_INET6
    src:网络字节序IP地址
    dst:本地字节序(string IP)size:dst的大小。
    返回值:成功: dsto失败:NULL

socaddr地址结构:

struct sockaddr_in addr ;
addr.sin_family = AF_INET/AF_INET6
addr.sin_port = htons(9527);
int dst ;
inet_pton(AF_INET“192.157.22.45"(void *)&dst) ;
addr. sin_addr.s_addr = dst;

【*】addr.sin_addr.s_addr = hton1(INADDR_ANY ); 取出系统中有效的任意IP地址。二进制类型。

  • bind(fd,(struct sockaddr *)&addrsize);

socket函数:

include <sys/socket.h>
int socket(int domain, int type, int protoco1);	
创建一个套接字
	domain: AF_INET、AF_INET6、AF_UNIX
	type: SOCK_STREAI、SOCK_DGRAM
	protocol: 0
	返回值:
		成功:新套接字所对应文件描述符
		失败: -1 errno

int bind(int sockfd,const struct sockaddr *addrsock1en_t adtrlen);		
给socket绑定一个地址结构(IP+port)
	sockfd: socket函数返回值
	struct sockaddr_in addr ;
	addr. sin_family = AF_INET;
	addr.sin_port = htons(8888) ;
	addr.sin_addr. s_addr = hton1 (INADDR_ANY) ;
	addr: (struct sockaddr *)&addr
	addrlen: sizeof(addr地址结构的大小。
	返回值:
		成功:0
		失败: -1 errno

int listen(int sockfd, int back1og);	
设置同时与服务器建立连接的上限数。(同时进行3次握手的客户端数量)
	sockfd: socket函数返回值
	backlog:上限数值。最大值128.
	返回值:
		成功:0
		失败:-1 errno

int accept(int sockfd, struct sockaddr *addrsocklen_t *addr1en);
阻塞等待客户端建立连接成功的话返回一个与客户端成功连接的socket文件描述符
	sockfd: socket函数返回值
	addr:传出参数。成功与服务器建立连接的那个客户端的地址结构IP+port)
		
		socklen_t clit_addr _len = sizeof(addr);
	addrlen:传入传出。&clit_addr_len
			入:addr的大小。出:客户端addr实际大小。
	返回值:
		成功:能与服务器进行数据通信的 socket对应的文件描述。
		失败:-1 , errno

int cornect(int sockfd,const struct sockaddr *addrsocklen_t addrlen);
使用现有的 socket与服务器建立连接
	sockfd: socket函数返回值
			struct sockaddr_in srv_addr ;		//服务器地址结木
			srv_addr.sin_farmi1y = AF_INET;
			srv_addr.sin_port = 9527			//跟服务器bind时设定的 port完全一致。
			inet_pton(AF_INET“服务器的IP地址"&srv_adrr.sin_addr.s_addr);
	addr:传入参数。服务器的地址结构
	addrlen:服务器的地址结构的大小
	返回值:
		成功:0
		失败: -1 errno
如果不使用bind绑定客户端地址结构采用"隐式绑定”.

CS模型TCP通信

服务端

int main(int argc,char *argv[])
{
	int lfd = 0,cfd = 0;
	int ret;
	char buf[BUFSIZ];//4096
	struct sockaddr_in serv_addr,clit_addr;
	socklen_t clit_addr_len;

	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(SERV_PROT);//SERV_PROT 9527
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	lfd = socket(AF_INET,SOCK_STREAM,0);		
	if(lfd = -1){
		//-1:error
	}
	
	bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
	
	listen(lfd,128);
	
	clit_addr_len = sizeof(clit_addr);
	cfd = accept(lfd,(struct sockaddr *)&clit_addr,&clit_addr_len);
	if(cfd == -1){
		//-1:error
	}
	ret = read(cfd,buf,sizeof(buf));
	//处理数据,转换成大写字母
	for(int i = 0;i < ret;i++)
		buf[i] = toupper(buf[i]);
	//
	write(cfd,buf,ret);
	close(lfd);
	close(cfd);
	return 0
} 

客户端

int main(){
	int cfd;
	char buf[BUFSIZ];
	
	struct sockaddr_in serv_addr;//服务器地址结构
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(9527);//SERV_PROT 9527
	inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin.s_addr ); 
	
	cfd = socket(AF_INET,SOCK_STREAM,0);
	if(cfd == -1){
		//error
	}
	int ret = connect(cfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
	if(ret != 0){
		//error
	}
	write(cfd,"hello",5);
	read(cfd,buf,sizeof(buf)); 
	return 0;
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux