网络通信TCP/UDP——学习笔记

30 篇文章 1 订阅
7 篇文章 0 订阅

参考文献:35 张图解被问千百遍的 TCP 三次握手和四次挥手面试题

一、网络通信的基本概念

1、TCP和UDP的区别

    TCP(Transmission Control Protocol):传输控制协议,面向连接的服务(类似打电话),安全、可
    靠(三次握手、响应+重传、四次挥手),速度相对较慢,一般应用在对安全性、完整性有严格要求的场景:文
    件传输(ftp)、SMTP、HTTP
        三次握手:
            A要知道,A能到B,B能到A
            B要也要知道,A能到B,B能到A
                         A 你听得到吗 ->       B(此时B知道了A能到B)
        (A能到B且B能到A)A <- 我能听到,你叫   B
                         A 我也能听到->        B(此时B知道了B也能到A)

        四次挥手:
            目的是保证关闭前发送完所有未发送的数据包(应用层已经交给底层了,但底层还没有完全发送出去)。
            A 发送关闭请求 -> B
            A <- 发送请求相应 B
                B检查 是否有未发送完成的数据
                <- 可以关闭   B
            A 发送关闭消息->  B

    UDP(User Datagram Protocol):用户数据报文协议,面向无连接的服务(发短信)0,不保证安全、
    可靠,但大多数情况下是可靠的,相对较快,流媒体(在线视频、音频)。
2、消息流
    应用层->表示层->会话层->传输层->网络层->数据链路层->物理层->数据链路层->网络层->传输层
    ->会话层->表示层->应用层
3、消息包
当socket收到一个要发送的数据时,会先把数据进行拆分成bit流,然后再组成(防丢失)数据包(可能会丢包)。

二、套接字

socket是一种接口机制,可以让程序无论使用什么端口、协议、都可以从socket进出数据,它负责了进程与协
议之间的连接。
1、编程模型
    点对点(p2p):一对一通信
    客户机/服务器(C/S):一对多通信
2、函数
    int socket(int domain, int type, int protocol);
    功能:创建socket描述符,可以把socket当作文件来看待,发送数据就是写文件,接收数据就是读文件。
    domain:地址类型
        AF_UNIX/AF_LOCAL/AF_FILE    本地通信(进程间通信)
        AF_INET                     基本32IP地址通信,IPv4 Internet protocols
        AF_INET6                    基本128IP地址通信,IPv6,IPv6 Internet protocols
    type:通信协议
        SOCK_STREAM     数据流协议,TCP
        SOCK_DGRAM      数据报协议,UDP
    protocol:特别通信协议,给0即可。
    返回值:socket描述符,类似文件描述符
3、通信地址
    注意:函数接口定义的是sockaddr,而实际提供的是sockaddr_un或sockaddr_in
    struct socketaddr{
        sa_family_t sa_family;
        char sa_data[14];
    }
    struct sockaddr_un {
        __SOCKADDR_COMMON(sun_); /* AF_UNIX */地址类型 参看domain参数 
        char sun_path[108]; /* pathname */socket文件的路径
    };
    struct sockaddr_in{
        __SOCKADDR_COMMON(sin_);
        in_port_t sin_port;     // 端口号 大端字节序 参看联合
        struct in_addr sin_addr // ip地址 大端4字节整数
    }
    struct in_addr{
        in_addr_t s_addr; // 
    }
4、绑定
	socket描述符与物理通信载体(网卡或socket文件)绑定在一起。
	int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
	sockfd:socket描述符:socket函数的返回值
	addr:通信地址结构体,实际给的是sockaddr_un或sockaddr_in,需要强制类型转换。
	addrlen:通信地址结构体类型的字节数,使用sizeof计算。
5、连接
	int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
	sockfd:socket描述符
	addr:通信目标地址
	addrlen:通信地址结构体类型的字节数,使用sizeof计算。
	返回值:在不同的编程模型下返回值意义不同,在本地通信
		返回加0,失败返回-1。
6、数据接收与发送:read/write
	ssize_t recv(int sockfd, void *buf, size_t len, int flags);
	ssize_t send(int sockfd, const void *buf, size_t len, int flags);
	recv/send与read/write功能一样,flags多了是否阻塞的功能(0阻塞,1不阻塞)。
7、关闭套接字:close
	如果是网络通信,端口号并不会立即回收,大概会占用3分钟左右。
8、字节序转换
#include <arpa/inet.h>

    uint32_t htonl(uint32_t hostlong);
    功能:把32位本机字节序转换成32位的网络字节序
    uint16_t htons(uint16_t hostshort);
    功能:把16位本机字节序转换成16位的网络字节序
    uint32_t ntohl(uint32_t netlong);
    功能:把32位网络字节序转换成32位的本机字节序
    uint16_t ntohs(uint16_t netshort);
    功能:把16位网络字节序转换成16位的本机字节序
9、ip地址转换
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
    int inet_aton(const char *cp, struct in_addr *inp);
    功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用指针获取。
    in_addr_t inet_addr(const char *cp);
    功能:把点分十进制的ip地址(字符串)转换成32位无符号整数,使用返回值直接返回。
    char *inet_ntoa(struct in_addr in);
    功能:32位无符号整数表示的ip地址,转换成点分十进制的ip地址(字符串)。
10、本地通信编程模型
    进程A                      进程B
    创建套接字(AF_LOCAL)      创建套接字(AF_LOCAL) 
    准备地址(sockaddr_un)     准备地址(sockaddr_un)
    绑定(自己的socket/地址)    连接(connect,连接进程A的地址)
    接收数据                    发送数据
    关闭套接字

三、基于TCP协议的C/S模型

int listen(int sockfd, int backlog);
	功能:设置等待连接的最大数量
	sockfd:被监听的socket描述符
	backlog:等待连接的最大数量(排队的数量)

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
	功能:等待连接sockfd连接
	addr:获取连接的地址
	addrlen:设置连接地址结构体的长度
	返回值:专门用于通信的描述符

编程模型:
    Server                                  Client
    创建socket套接字                         创建socket套接字
    准备地址(sockaddr_in,本机地址)          准备地址(服务器地址)
    绑定(bind)                             。。。
    监听(listen)                           。。。
    等待连接(accept、fork)                 连接(connect)
    接收请求(read/recv)                      发送请求(write/send)
    响应请求(write/send)                     接收响应(read/recv)                    
    关闭(close)                              关闭(close)

四、基于UDP协议的C/S模型

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,  const struct sockaddr *dest_addr, socklen_t addrlen);
功能:UDP协议专用的数据发送函数
	sockfd:套接字描述符
	buf:待发送的缓冲区首地址
	len:待发送的数据字节数
	flags:0阻塞,1不阻塞
	dest_addr:目标计算机地址(发送)
	addrlen:地址结构体的字节数
	返回值:成功发送的字节数

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
功能:UDP协议专用的数据接收函数
	sockfd:套接字描述符
	buf:数据存储位置 
	len:最大接收字节数
	flags:0阻塞,1不阻塞
	src_addr:获取发送者的地址
	addrlen:设置地址结构体的字节数
	返回值:成功接收的字节数。

编程模型:
Server                                  Client
创建套接字(socket)                     创建套接字(socket)   
准备地址(本机地址sockaddr_in)           准备地址(目标机地址sockaddr_in)
绑定(bind(sockfd+addr))              。。。
接收请求(recvfrom)                     发送请求(sendto)
响应请求(sendto)                       接收响应(recvfrom)
关闭套接字(close)                      关闭套接字(close)
注意:从服务器到客户端返回的路线是UDP协议自己设计的。

实例

C语言实现socket通信TCP 程序参考
在这里插入图片描述

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love丶伊卡洛斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值