推荐文章:
Liunx系列:
2、Linux进阶命令 任务编程系列:
IP地址的介绍
1、IP地址概念
IP地址就是标识网络中设备的一个地址,好比现实生活中的家庭地址。
网络中的设备效果图:
2、IP地址的表现形式
说明:
3、IP地址的作用
IP地址的作用是表示网络中唯一的一台设备的,也就是说通过IP地址能够找到网络中某台设备。
4、查看IP地址
5、检查网络是否正常
说明:
6、小结
端口和端口号的介绍
1、问题思考
不同电脑上的飞秋之间进行数据通信,它是如何保证把数据给飞秋而不是给其他软件呢?
其实,每运行一个网络程序都会有一个端口,想要给队员的程序发送数据,找到对应的端口即可。
端口效果图:
2、什么是端口
端口是传数据的通道,好比教室的门,是数据传输的必经之地。
那么如何准确的找到对应的端口呢?
其实,每一个端口都会有一个对应的端口号,好比每个教室的门都有一个门牌号,想要找到端口通过端口号即可。
端口号效果图:
3、什么是端口号
操作系统为了统一管理这么多端口,就对端口进行了编号,这就是端口号,端口号其实就是一个数字,好比我们现实生活中的门牌号。
端口号有65535个
那么最终飞秋之间进行数据通信的流程是这样的,通过IP地址找到对应的设备,通过端口号找到对应的端口,然后通过端口把数据传输给应用程序。
最终通信流程效果图:
4、端口和端口号的关系
端口号可以标识唯一的一个端口。
5、端口号的分类
知名端口号:
动态端口号:
一般程序员开发应用程序使用端口号称为动态端口号,范围是从1024到65535.
6、小结
TCP的介绍
1、网络应用程序之间的通信流程
之前学习了IP地址和端口号,通过IP地址能够找到对应的设备,然后再通过端口号找到对应的端口,再通过端口把数据传输给应用程序,这里要注意,数据不能随便发送,在发送之间还需要选择一个对应的传输协议,保证程序之间按照指定的传输规则进行数据的通信,而这个传输协议就是我们接下来要学习的TCP。
2、TCP的概念
TCP简称传输控制协议,它是一种面向链接的、可靠的、基于字节流的传输层通信。
面向连接的效果图:
TCP通信步骤:
说明:
TCP通信模型相当于生活中的“打电话”,在通信开始之前,一定要先建立好连接,才能发送数据,通信结束要关闭。
3、TCP的特点
4、总结
TCP是一个稳定、可靠的传输协议,常用于对数据进行准确无误的传输,比如:文件下载,浏览器上网。
socket的介绍
1、问题思考
到目前为止,我们了解了IP地址和端口号还有tcp协议,为了保证数据的完整性和可靠性我们使用tcp传输协议进行数据的传输,为了能够找到对应设备我们需要使用IP地址,为了区别某个端口的应用程序接收数据我们使用端口号,那么通信数据时如何完成传输的呢?
使用socket来完成的
2、socket的概念
socket(简称套接字)是进程之间进行通信的一个工具,好比现实生活中的插座,所有的家用电器想要工作都是基于插座进行,进程之间想要进行网络通信要基于这个socket。
socket效果图:
3、socket的作用
负责进程之间的网络数据传输,好比数据的搬运工。
4、socket使用场景
毫不夸张的说,只要跟网络相关的应用程序或者软件都使用到了socket。
5、小结
进程之间网络数据的传输可以通过socket来完成,socket就是进程间网络数据通信的工具。
TCP网络应用程序的开发流程
1、TCP网络应用程序开发流程的介绍
TCP网络应用程序开发分为:
说明:
客户端程序是指运行在用户设备上的程序。
服务端程序是指运行在服务器设备上的程序,专门为客户端提供数据服务。
2、TCP客户端程序开发流程的介绍
步骤说明:
3、TCP服务端程序开发流程的介绍
步骤说明:
4、小结
TCP客户端程序开发
1、开发TCP客户端程序步骤回顾
2、socket类的介绍
导入socket模块
import socket
创建客户端socket对象
socket.socket(AddressFamily, Type)
参数说明:
方法说明:
3、TCP客户端程序开发示例代码
# -*- codeing = utf-8 -*-
# @Time : 2021/12/8 9:07 下午
# @Author : 李明辉
# @File : ithui_tcp客户端程序开发.py
# @Software : PyCharm
import socket
if __name__ == '__main__':
# 1、建立tcp客户端套接字
# AF_INET:ipv4地址类型
# SOCK_STREAM:tcp传输协议的类型
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、和服务端套接字建立连接
tcp_client_socket.connect("192.168.22.75", 9090)
send_content = "你好,我是客户端小明!" # input()
# 对字符串进行编码成为二进制数据
# windows里面的网络调试助手使用的是gbk编码
# Linux里面的网络调试助手使用的是utf-8编码
send_data = send_content.encode("utf-8")
# 3、发送数据到服务端
tcp_client_socket.send(send_data)
# 4、接受服务端的数据
# 1024:表示每次接收的最大字节数
recv_data = tcp_client_socket.recv(1024)
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
print("接受服务端的数据为:", recv_content)
# 5、关闭套接字
tcp_client_socket.close()
TCP服务端程序开发
1、开发TCP服务端程序步骤回顾
2、socket类的介绍
导入socket模块
import socket
创建服务端socket对象
socket.socket(AddressFamily, Type)
参数说明:
方法说明:
3、TCP服务端程序开发示例代码
# -*- codeing = utf-8 -*-
# @Time : 2021/12/8 9:43 下午
# @Author : 李明辉
# @File : ithui_tcp服务端程序开发.py
# @Software : PyCharm
import socket
if __name__ == '__main__':
# 1、创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、绑定端口号
# 第一个参数表示ip地址,一般不用指定,表示本机任何一个ip即可
# 第二个表示端口号
tcp_server_socket.bind("", 9090)
# 3、设置监听
# 128表示最大等待建立连接个数
tcp_server_socket.listen(128)
# 4、等待接收客户端的连接请求
# 注意点:每次当客户端和服务端建立连接成功都会返回一个新的套接字
# tcp_server_socket只负责等待接收客户端的连接请求,收发消息不实用该套接字
new_client, ip_port = tcp_server_socket.accept()
# 代码执行到此,说明客户端和服务端建立连接成功
print("客户端的ip和端口号为:", ip_port)
# 5、接收客户端的数据
# 收发消息都使用返回的新的套接字
recv_data = new_client.recv(1024)
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
print("接收客户端的数据为", recv_content)
# 6、发送数据到客户端
send_content = "问题正在处理中..."
# 对字符串进行处理
send_data = send_content.encode("utf-8")
new_client.send(send_data)
# 关闭服务端与客户端套接字,表示和客户端终止通信
new_client.close()
# 7、关闭服务端套接字,表示服务端不再等待接受客户端的连接请求
tcp_server_socket.close()
说明:
当客户端和服务端建立连接后,服务端程序退出后端口号不会立即释放,需要等待1-2分钟。
解决方法有两种:
设置端口号复用的代码如下:
# 参数1:表示当前套接字
# 参数2:设置端口号复用选项
# 参数3:设置端口号复用选项对应的值
tcp_server_socket.setsocketopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
TCP网络应用程序的注意点
案例 - 多任务版TCP服务端程序开发
1、需求
目前我们开发的TCP服务端程序只能服务于一个客户端,如何开发一个多任务的TCP服务端程序能够服务多个客户端呢?
完成多任务,可以使用线程,比进程更节省内存资源
2、具体实现步骤
3、多任务版TCP服务端程序的示例代码:
代码演示:
# -*- codeing = utf-8 -*-
# @Time : 2021/12/9 7:55 下午
# @Author : 李明辉
# @File : ithui_服务端服务于多个客户端.py
# @Software : PyCharm
import socket
import threading
# 处理客户端请求的任务
def handle_client_request(ip_port, new_client):
print("客户端的ip和端口号为:", ip_port)
# 5、接收客户端的数据
# 收发消息都使用返回的新的套接字
# 循环接收客户端的消息
while True:
recv_data = new_client.recv(1024)
if recv_data:
# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
print("接收客户端的数据为", recv_content, ip_port)
# 6、发送数据到客户端
send_content = "问题正在处理中..."
# 对字符串进行处理
send_data = send_content.encode("utf-8")
new_client.send(send_data)
else:
# 客户端关闭连接
print("客户端下线了:", ip_port)
break
# 关闭服务端与客户端套接字,表示和客户端终止通信
new_client.close()
if __name__ == '__main__':
# 1、创建套接字对象
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、绑定端口号
# 第一个参数表示ip地址,一般不用指定,表示本机任何一个ip即可
# 第二个表示端口号
tcp_server_socket.bind("", 9090)
# 3、设置监听
# 128表示最大等待建立连接个数
tcp_server_socket.listen(128)
# 4、等待接收客户端的连接请求
# 注意点:每次当客户端和服务端建立连接成功都会返回一个新的套接字
# tcp_server_socket只负责等待接收客户端的连接请求,收发消息不实用该套接字
# 循环等待接受客户端的连接请求
while True:
new_client, ip_port = tcp_server_socket.accept()
# 代码执行到此,说明客户端和服务端建立连接成功
# 当客户端和服务端建立连接成功,创建子线程,让子线程专门负责接收客户的信息
sub_thread = threading.Thread(target=handle_client_request, args=(ip_port, new_client))
# 设置守住主线程,主线程退出子线程直接销毁
sub_thread.setDaemon(True)
# 启动子线程,执行对应的任务
sub_thread.start()
# 7、关闭服务端套接字,表示服务端不再等待接受客户端的连接请求
# tcp_server_socket.close() # 因为服务端的程序需要一直运行,所以关闭服务端套接字可以不关闭
socket之send和recv原理剖析
1、认识TCP socket的发送和接受缓冲区
当创建一个TCP socket对象的时候会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区指的就是内存中的一片空间。
2、send原理剖析
send是不是直接把数据发给服务端?
不是,要想发数据,必须得通过网卡发送数据,应用程序是无法直接通过网卡发送数据的,它需要调用操作系统接口,也就是说,应用程序把发送的数据写入到发送缓冲区(内存中的一片空间),再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡。
3、recv原理剖析
recv是不是直接从客户端接收数据?
不是,应用软件是无法直接通过网卡接收数据的,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区(内存中的一片空间),应用程序再从接收缓冲区获取客户端发送的数据。
4、send和recv原理剖析图
说明:
5、小结
不管是recv还是send都不是直接收到对方的数据和发送数据到对方,发送数据会写入到发送缓冲区,接收数据是从接收缓冲区来读取的,发送数据和接收数据最终是由操作系统控制网卡来完成。
END