当前位置:网站首页>服务器和客户端的套接字通信
服务器和客户端的套接字通信
2022-04-21 06:35:00 【小学五年级在读的蒟蒻】
服务器和客户端的套接字通信
大家好,我是小学五年级在读的蒟蒻,专注于后端,一起见证蒟蒻的成长,您的评论与赞与关注是我的最大动力,如有错误还请不吝赐教,万分感谢。一起支持原创吧!纯手打有笔误还望谅解。
-
TCP/IP的四层参考模型,从上到下分别是:应用层,传输层,网络层,网络接口层。
-
应用层协议:HTTP,FTP,DNS等
-
传输层协议:TCP,UDP
-
网络互连层协议:IP,ARP,RARP,ICMP
-
网络接口层协议:Ethernet,ISDN等
-
-
在TCP/IP四层参考模型中,从上往下有四种层次:应用层,传输层,网络层,网络接口层,应用层包括HTTP,FTP,DNS等协议,而传输层包括TCP,UDP两种协议,网络层则包含IP,ARP等协议,网络接口层较为底层。
-
传输层的作用
-
传输层的根本目的是在网络层提供的数据通信服务基础上,实现主机的进程间通信的可靠服务。
-
有以下两个要点:位于两个主机内部的两个应用进程之间提供通信服务,提供可靠的通信服务
-
-
套接字(socket)
-
是一个套用C语言写成的应用程序开发库,实现进程间通信和网络编程
-
套接字是一个抽象层,应用程序可以通过它发生和接收数据,可对其进行想对文件一样的打开,读写和关闭等操作。套接字允许应用程序与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合
-
-
端口(port)
-
在计算机中,端口大致有两种意思:一是物理意义上的端口,比如RJ45,集线器,交换机,路由器等
-
二是逻辑意义上的端口,一般指TCP/IP协议中的端口,端口号的范围从0到65535,比如浏览网页的80端口,FTP服务的21端口
-
在TCP中一般都是软件形式的端口,根据提供的服务不同,一般可分为两种
-
TCP端口
-
特点
-
面向连接的传输服务。打电话式,会话式通信
-
面向字节流传输的通信(而UDP是面向报文通信)。字节管道,字节按序传输和到达
-
全双工通信.一个应用进程可以同时接收和发送数据,捎带确认;通信双方都设置有发送和接收缓冲区,应用程序将要发送的数据字节提交给发送缓冲区,实际发送由TCP协议控制,接收方收到数据字节后将它接收放在缓冲区,等待高级应用程序读取
-
可建立多个并发的TCP连接.如Web服务器可同时与多个用户程序建立连接会话.
-
可靠传输服务.不丢失数据,保持数据有序,向上不重复提交数据(通过确认机制,拥塞控制等方式实现),想象一下ATM机转账应用就需要上述的可靠性
-
-
-
UCP端口
-
特点
-
无连接:在发送数据之前不需要建立连接,因此减少了开销和发送数据前的时间
-
仅最大努力交付:即不保证可靠交付,因此主机不需要维持复杂的连接状态表
-
面对报文的:UDP对于应用层传递下来的报文,既不合并,也不拆分,而是保留这些报文的编辑。UDP对于应用程序提交的报文,添加头部后就向下提交给网络层
-
支持多对多的交互通信
-
-
适用场景
-
适用于少量(几百个字节)的数据
-
对性能的要求高于数据完整的要求,如播放视频,P2P,DNS等
-
需要”简短快捷 “的数据交换 简单的请求与应答报文交互,如在线游戏
-
需要多播和广播的应用,源主机以恒定的速率发送报文,拥塞时允许丢弃部分报文,如本地广播,隧道VPN。
-
-
-
-
端口分类
-
熟知端口号:给每种服务器分配的确定的全局端口号,每个用户进程都知道的相应的服务器进程的熟知端口号,范围是0-1023,它是统一分配和控制的
-
注册端口号:在IANA注册的端口号,数值范围为1024-49151
-
临时端口号:客户端程序使用的零时端口号,它是运行在客户端上的TCP/IP软件随机选取的,范围在49152-65535
-
平时网络编程,服务器一般使用注册端口号,而客户端的端口号则是系统随机分配的,即临时端口号
-
-
TCP报文图
重点的标志位和意义
-
-
TCP的三次握手过程
-
TCP的连接包括连接建立,报文传输,连接释放三个阶段,其中连接建立的三次握手过程较为重要.
-
建立三次握手的过程
-
客户端准备发起一次TCP连接,首先向服务器发送第一个"SYN"报文(控制位SYN=1)
-
服务器收到SYN报文后,如果同意建立连接,则向客户端发送第二个"SYN+ACK"报文(控制位 SYN=1,ACK=1),该报文表示对第一个SYN报文请求的确认
-
接收到SYN+ACK报文后,客户端发送第三个ACK报文,表示对SYN+ACK报文的确认
-
-
-
用C++进行TCP套接字网络编程
- 网络编程中我们一般会使用C/S架构,即包含服务器端和客户端
-
TCP网络编程的服务器端
-
服务器端一般先用socket创建一个套接字,然后用bind给这个套接字绑定地址(IP和端口号),然后调用listen把这个套接字设置为监听状态,随后调用accept函数从已完成连接队列中取出成功建立连接的套接字,以后就在这个新的套接字上调用spend,recv来发送数据,接收数据,最后调用close来断开连接释放资源即可
过程
-
-
TCP网络编程的客户端
-
与服务器不同,客户端并不需要bind绑定地址,因为端口号是系统自动分配的,而且客户端也不需要设置监听的套接字,因此也不需要listen.客户端在用socket创建套接字后直接调用connect向服务器发起连接即可,connect函数通知Linux内核完成TCP三次连接握手,最后将连接的结果作为返回值.成功建立连接后我们就可以调用send和recv来发送数据,接收数据,最后调用close来断开连接释放资源
过程
-
-
完整流程
TCP网络编程的整体流程
-
TCP网络编程的相关数据结构
-
地址结构:
-
sockaddr
-
在头文件 #include<sys/socket.h> 中定义
-
缺陷:sa_data把目标地址和端口信息混在一起了
struct sockaddr { sa_family_t sin_family;//地址族 char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息 };
-
-
sockaddr_in
-
在头文件#include<netinet/in.h>或#include<arepa/inet.h>中定义
-
该结构体解决了sockaddr的缺陷,将port和addr分开存储在两个变量中
struct sockaddr_in{ short int sin_family;//地址族 unsigned short int sin_port;//端口号 struct in_addr sin_addr;//ip地址 unsigned char sin_zero[8];//不使用 };该结构体中提到的另一个结构体in_addr定义如下,用来存放32位IP地址
struct in_addr { unsigned long s_addr;//32位IPv4地址 };
-
-
-
sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO).
-
TCP网络编程各函数的定义
-
socket():creating a socket
int socket(int domain,int type,int protocol); return file(socket)descriptor if OK,-1 on error; /* 功能:创建一个新的套接字,返回套接字描述 参数说明: domain:域类型,指明使用的协议栈,如tcp使用的是PF_INET,还有AF_INET6,AFUNIX等 tyoe:指明需要服务的类型,如 SOCK_DGRAM:数据报服务,UDP协议 SOCK_STREAM:刘服务,TCP协议 protocol:一般都取0(由系统根据服务类型选择默认的协议) */ -
bind():binding a socket to an address
int bind(int sockfd,const struct sockaddr* my_addr, socklen_t addrlen); return 0 on success,or -1 on error /* 功能:为套接字绑定地址 TCP/IP协议使用sockaddr_in结构,包含IP地址和端口号,服务器使用它来 指明熟知的端口号,然后等待连接 参数说明: sockfd:套接字描述符,指明创建连接的套接字 my_addr:本地地址,IP地址和端口号 addrlen:地址长度 */ -
listen():listening for incoming connections
int listen(int sockfd,int backlog); return 0 on success,or -1 on error /* 功能: 将一个套接字设置为监听模式,准备接收传入连接.用于服务器,指明某个套接字 连接是被动的监听状态 参数说明: Sockfd:套接字描述符,指明创建连接的套接字 backlog:linux内核2.2之前,backlog参数=半连接队列长度+已连接队列长度; linux内核之后,backlog参数=已连接队列(Accept队列)长度 */ -
accept():accepting a connection
int accept(int sockfd,struct sockaddr *restrict_addr, socklen_t *restrict_len); return file(socket)descriptor if OK,-1 on error /* 功能:从已完成连接队列中取出成功建立连接的套接字, 返回成功连接的套接字描述符. Sockfd:套接字描述符,指明正在监听的套接字 addr:提出连接请求的主机地址 addrlen:地址长度 */ -
send():TCP类型的数据发送
int send(int sockfd,const void *msg,int len,int flags); /* 功能:在TCP连接上发送数据,返回成功传送数据的长度,出错时返回-1. send会将数据移到发送缓冲区中. 参数说明: sockfd:发送端套接字描述符(非监听描述符) msg:待发送数据的缓冲区(将其内容的len长度拷贝到socket的发送缓冲区), 其类型是指针,指向发送数据的缓冲区 len:待发送数据的字节长度 flags:一般情况下置为0 */ -
recv():TCP类型的数据接收
int recv(int sockfd,void *buf,int len,unsigned int flags); /* 功能:接收数据,返回实际接收的数据长度,出错返回-1 参数说明: sockfd:套接字描述符 buf:指向内存块的指针 buf_len:内存块大小,以字节为单位 flags:一般情况下置为0 */ -
close():撤销套接字
connect():connecting to a peer socket
close(int sockfd) /* 功能:撤销套接字.如果只有一个进程使用,立即终止连接并撤销该套接字, 如果多个进程共享该套接字,则将引用数减一,直到引用数降到0, 则关闭连接撤销套接字. 参数说明: sockfd:套接字描述符 */ int connect(int sockfd,structsockaddr *server_addr, int sockaddr_len); /* 功能:同远程服务器建立主动连接,成功时返回0,若连接失败返回-1. 参数说明: sockfd:套接字描述符,指明创建连接的套接字 server_addr:指明远程端点:IP地址和端口号 sockaddr_len:地址长度 */
-
-
-
-
实战练习
- 编写两个程序:一个服务器,一个客户端,让用户能够在客户端不断输入信息并发送到服务器终端上显示.
-
服务器程序编程
-
新建serve.cpp文件,在其中写服务器的代码:
#include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<fcntl.h> #include<sys/shm.h> #include<iostream> using namespace std; int main() { //定义sockfd int server_sockfd = socket(AF_INET,SOCK_STREAM,0); //定义sockaddr_in struct sockaddr_in server_sockaddr; server_sockaddr.sin_family = AF_INET;//TCP/IP协议族 server_sockaddr.sin_port=htons(8023);//端口号 server_sockaddr.sin_addr.s_addr=inet_addr("127.0.0.1");//ip地址,127.0.0.1 //bind,成功返回0,出错返回-1 if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))) { perror("bind");//输出错误原因 exit(1);//结束程序 } //listen,成功返回0,出差返回-1 if(listen(server_sockfd,20)==-1) { perror("listen");//输出错误原因 exit(1);//结束程序 } //客户端套接字 struct sockaddr_in client_addr; socklen_t length=sizeof(client_addr); //成功返回非负描述字,出错返回-1 int conn=accept(server_sockfd,(struct sockaddr*)&client_addr,&length); if(conn<0) { perror("connect");//输出错误原因 exit(1);//结束程序 } //接收缓冲区 char buffer[1000]; //不断接收数据 while(1) { memset(buffer,0,sizeof(buffer)); int len=recv(conn,buffer,sizeof(buffer),0); //客户端发送exit或异常结束时,退出 if(strcmp(buffer,"exit")==0||len<=0) break; cout<<"收到客户端信息:"<<buffer<<endl; } close(conn); close(server_sockfd); return 0; } -
client.cpp
#include<sys/types.h> #include<sys/socket.h> #include<stdio.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<string.h> #include<stdlib.h> #include<fcntl.h> #include<sys/shm.h> #include<iostream> using namespace std; int main() { //定义sockfd int sock_cli=socket(AF_INET,SOCK_STREAM,0); //定义sockaddr_in struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(servaddr)); servaddr.sin_family=AF_INET;//TCP/IP协议族 servaddr.sin_port=htons(8023);//服务器端口 servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器ip //连接服务器,成功返回0,错误返回-1 if(connect(sock_cli,(struct sockaddr *)&servaddr,sizeof(servaddr))) { perror("connect"); exit(1); } cout<<"连接服务器成功!"<<endl; char sendbuf[100]; char recvbuf[100]; while(1) { memset(sendbuf,0,sizeof(sendbuf)); cin>>sendbuf; send(sock_cli,sendbuf,strlen(sendbuf),0);//发送 if(strcmp(sendbuf,"exit")==0) { break; } } close(sock_cli); return 0; }
-
版权声明
本文为[小学五年级在读的蒟蒻]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_44229867/article/details/124280810
边栏推荐
- 【WPF】利用RadioButton制作导航条
- 计算机漏洞安全相关的概念POC 、EXP 、VUL 、CVE 、0DAY
- 排序方式(2)==>插入排序
- Three layer switch and router are connected to the Internet
- NP and OSPF default routes
- Convergencewarning: Free failed to converse, increase the number of iterations Solutions
- NP、OSPF基本配置
- 【C#】重塑矩阵(交错数组)
- Troubleshooting NP and OSPF
- Ruiyuan ry8132 and ry9140 DCDC are mainly replaced by tps563200 and tps563201 of Ti, mp1471 and mp1653 of Xinyuan, and details of sy8104 power chip of silijie
猜你喜欢

NP, OSPF stub area

OSPF多区域

ConvergenceWarning: Liblinear failed to converge, increase the number of iterations解决辦法

NP, OSPF route aggregation

【WPF】自定义Combobox

【WPF】级联Combobox

Sorting method (3) = > quick sort and merge sort

Common weak passwords in network security devices

IGMP_ Huawei

Configure MySQL remote access
随机推荐
Concepts related to computer vulnerability security POC, exp, vul, CVE, 0day
NP、OSPF 缺省路由
Define a standard class
论文阅读:Measuring the Global Recursive DNS Infrastructure: A View From the Edge
Sort method (2) = > insert sort
中介者模式(3.28-4.3)
写入数据进入磁盘文件代码示例如下:
解释器模式(3.7-3.13)
【C#】重塑矩阵(交错数组)
Ruiyuan power chip, ry3715, ry3750 replacement: silijie sy7208, sy7152, Xinpeng micro ap2008 Core source mp1542, mp3213. Input voltage from 2.5V to 5.5V
状态模式(4.4-4.10)
Longxun series video conversion, lt9211, lt8918, functions: LVDS to bt656, LVDS to Mipi (CSI \ DSI) RGB to Mipi (DSI \ CSI) bt656 \ 601 \ 1120 to hdmi1 4\DVI
数据库日志级别解析:(2022.2.21-2022.2.27)
Use the security vulnerability detection tool Metasploit to lift the telnet login right of the target metasploitabile2
IPV4-IGP
OSPF多区域
NP、OSPF路由聚合
PIM-DM
Detailed explanation of the whole evolution process and architecture design of large websites
【WPF】Popup