当前位置:网站首页>网络通信及相关函数介绍
网络通信及相关函数介绍
2022-08-05 05:16:00 【乛 乛 .】
1. 网络通信概述
1.1 IP和端口
所有的数据传输,都有三个要素 :源、目的、长度
所以,在网络传输中需要使用“IP和端口”来表示源或目的。
1.2 网络传输中的2个对象:server和client
我们经常访问网站,这涉及2个对象:网站服务器,浏览器。网站服务器平时安静地呆着,浏览器主动发起数据请求。网站服务器、浏览器可以抽象成2个软件的概念:server程序、client程序。
![在这里插入图片描述](https://img-blog.csdnimg.cn/80b15039e0a84722ac8c5cc3988a69d1.png)
1.3 两种传输方式:TCP/UDP
在一般情况下,网络协议被分为5层,如下图所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/0c849a59441e4290a1231cabc5e9760a.png)
应用层:它是体系结构中的最高层,直接为用户的应用进程(例如电子邮件、文件传输和终端仿真)提供服务。在因特网中的应用层协议很多,如支持万维网应用的HTTP协议,支持电子邮件的SMTP协议,支持文件传送的FTP协议,DNS,POP3,SNMP,Telnet等等,我们的应用程序位于“应用层”。
运输层:负责向两个主机中进程之间的通信提供服务。
运输层主要使用以下两种协议:
(1) 传输控制协议TCP(Transmission Control Protocol):面向连接的,数据传输的单位是报文段,能够提供可靠的交付。
(2) 用户数据包协议UDP(User Datagram Protocol):无连接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“尽最大努力交付”。
网络层:负责将被称为数据包(datagram)的网络层分组从一台主机移动到另一台主机。
链路层:因特网的网络层通过源和目的地之间的一系列路由器路由数据报。
物理层:在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。
使用“运输层”时,可以选择TCP协议,也可以选择UDP协议。
- TCP和UDP 原理上的区别
TCP向它的应用程序提供了面向连接的服务。这种服务有2个特点:可靠传输、流量控制(即发送方/接收方速率匹配)。它包括了应用层报文划分为短报文,并提供拥塞控制机制。
UDP协议向它的应用程序提供无连接服务。它没有可靠性,没有流量控制,也没有拥塞控制。 - 为何存在UDP协议
既然TCP提供了可靠数据传输服务,而UDP不能提供,那么TCP是否总是首选呢?
答案是否定的,因为有许多应用更适合用UDP,举个例子:视频通话时,使用UDP,偶尔的丢包、偶尔的花屏时可以忍受的;如果使用TCP,每个数据包都要确保可靠传输,当它出错时就重传,这会导致后续的数据包被阻滞,视频效果反而不好。
使用UDP时,有如下特点:
a. 关于何时发送什么数据控制的更为精细
采用UDP时只要应用进程将数据传递给UDP,UDP就会立即将其传递给网络层。而TCP有重传机制,而不管可靠交付需要多长时间。但是实时应用通常不希望过分的延迟报文段的传送,且能容忍一部分数据丢失。
b. 无需建立连接,不会引入建立连接时的延迟。
c. 无连接状态,能支持更多的活跃客户。
d. 分组首部开销较小。 - TCP/UDP网络通信大概交互图
1.2 网络编程主要函数介绍
1.2.1 socket函数
int socket(int domain, int type,int protocol);
此函数用于创建一个套接字。
domain是网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等)。
AF_UNIX只能够用于单一的Unix 系统进程间通信,而AF_INET是针对Internet的,因而可以允许远程通信使用。
type是网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM等)。
SOCK_STREAM表明用的是TCP 协议,这样会提供按顺序的,可靠,双向,面向连接的比特流。
SOCK_DGRAM 表明用的是UDP协议,这样只会提不可靠,无连接的通信。
关于protocol,由于指定了type,所以这个地方一般只要用0来代替就可以了。
此函数执行成功时返回文件描述符,失败时返回-1,看errno可知道出错的详细情况。
1.2.2 bind函数
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
从函数用于将地址绑定到一个套接字。
sockfd是由socket函数调用返回的文件描述符。
my_addr是一个指向sockaddr的指针。
addrlen是sockaddr结构的长度。
sockaddr的定义:
struct sockaddr{
unisgned short as_family;
char sa_data[14];
};
不过由于系统的兼容性,我们一般使用另外一个结构(struct sockaddr_in) 来代替。
sockaddr_in的定义:
struct sockaddr_in{
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
}
如果使用Internet所以sin_family一般为AF_INET。
sin_addr设置为INADDR_ANY表示可以和任何的主机通信。
sin_port是要监听的端口号。
bind将本地的端口同socket返回的文件描述符捆绑在一起.成功是返回0,失败的情况和socket一样。
1.2.3 listen函数
int listen(int sockfd,int backlog);
此函数宣告服务器可以接受连接请求。
sockfd是bind后的文件描述符。
backlog设置请求排队的最大长度。当有多个客户端程序和服务端相连时,使用这个表示可以介绍的排队长度。
listen函数将bind的文件描述符变为监听套接字,返回的情况和bind一样。
1.2.4 accept函数
int accept(int sockfd, struct sockaddr *addr,int *addrlen);
服务器使用此函数获得连接请求,并且建立连接。
sockfd是listen后的文件描述符。
addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了, bind,listen和accept是服务器端用的函数。
accept调用时,服务器端的程序会一直阻塞到有一个客户程序发出了连接。 accept成功时返回最后的服务器端的文件描述符,这个时候服务器端可以向该描述符写信息了,失败时返回-1 。
1.2.5 connect函数
int connect(int sockfd, struct sockaddr * serv_addr,int addrlen);
可以用connect建立一个连接,在connect中所指定的地址是想与之通信的服务器的地址。
sockfd是socket函数返回的文件描述符。
serv_addr储存了服务器端的连接信息,其中sin_add是服务端的地址。
addrlen是serv_addr的长度
connect函数是客户端用来同服务端连接的.成功时返回0,sockfd是同服务端通讯的文件描述符,失败时返回-1。
1.2.6 send函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
sockfd 指定发送端套接字描述符;
buf 指明一个存放应用程序要发送数据的缓冲区;
len 指明实际要发送的数据的字节数;
flags 一般置0。
客户或者服务器应用程序都用send函数来向TCP连接的另一端发送数据
1.2.7 recv函数
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
sockfd 指定接收端套接字描述符;
buf 指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
len 指明buf的长度;
flags 一般置0。
客户或者服务器应用程序都用recv函数从TCP连接的另一端接收数据。
1.2.8 recvfrom函数
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
recvfrom通常用于无连接套接字,因为此函数可以获得发送者的地址。
src_addr 是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号。
addrlen 常置为sizeof (struct sockaddr)。
1.2.9 sendto函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
sendto和send相似,区别在于sendto允许在无连接的套接字上指定一个目标地址。
dest_addr 表示目地机的IP地址和端口号信息,
addrlen 常常被赋值为sizeof (struct sockaddr)。
sendto 函数也返回实际发送的数据字节长度或在出现发送错误时返回-1。
1.3 网络编程一般步骤
1.3.1 对于tcp连接
1.服务器端1)创建套接字socket;2)绑定端口号bind;3)监听连接listen;4)接受连接请求accept,并返回新的套接字;5)用新返回的套接字recv/send;6)关闭套接字。
2.客户端1)创建套接字socket; 2)发起建立连接请求connect; 3)发送/接收数据send/recv;4)关闭套接字。
TCP总结:
Server端:socket-- bind – listen-- accept-- recv/send-- close
Client端:connect------- conncet------send/recv------close.
1.3.1 对于udp连接
1.服务器端:1)创建套接字socket;2)绑定端口号bind;3)接收/发送消息recvfrom/sendto;4)关闭套接字。
2.客户端:1)创建套接字socket;2)发送/接收消息sendto/recvfrom;3)关闭套接字.
UDP总结:
Server端:socket----bind ----recvfrom/sendto----close
Client端:connect---- sendto/recvfrom----close.
————————————————
网络编程的一般步骤
边栏推荐
- [Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)
- CVPR 2020 - 频谱正则化
- 【论文阅读-表情捕捉】ExpNet: Landmark-Free, Deep, 3D Facial Expressions
- tensorflow的session和内存溢出
- 《基于机器视觉测量系统的工业在线检测研究》论文笔记
- 【论文精读】Rich Feature Hierarchies for Accurate Object Detection and Semantic Segmentation(R-CNN)
- 【论文阅读-表情捕捉】High-quality Real Time Facial Capture Based on Single Camera
- ACL 的一点心得
- 【论文精读】R-CNN 之预测框回归(Bounding box regression)问题详述
- 表情捕捉的指标/图像的无参考质量评价
猜你喜欢
随机推荐
MySQL主从复制—有手就能学会的MySQL集群搭建教程
吞吐?带宽?傻傻分不清楚
【数据库和SQL学习笔记】3.数据操纵语言(DML)、SELECT查询初阶用法
dataframe 常用操作
【论文精读】ROC和PR曲线的关系(The relationship between Precision-Recall and ROC curves)
ECCV2022 | RU&谷歌提出用CLIP进行zero-shot目标检测!
MySQL
Tensorflow踩坑笔记,记录各种报错和解决方法
盘点关于发顶会顶刊论文,你需要知道写作上的这些事情!
表情捕捉的指标/图像的无参考质量评价
物联网:LoRa无线通信技术
LeetCode刷题之第746题
Thread handler句柄 IntentServvice handlerThread
Detailed explanation of BroadCast Receiver (broadcast)
2021电赛资源及经验总结
八、请求处理之自定义类型参数绑定原理
Tensorflow steps on the pit notes and records various errors and solutions
【数据库和SQL学习笔记】7.SQL中的插入(INSERT)、删除(DELETE)、更新(UPDATE)
五、请求处理—Rest映射是怎样实现的?
面向小白的深度学习代码库,一行代码实现30+中attention机制。