IP地址的介绍
IP地址就是标识网络中设备的一个地址
IP地址的表现形式
- IPv4 目前使用的IP
点分十进制 - IPv6 未来使用的地址
冒号分十六进制
IPv4地址不够用,所以又分了共有IP和私有IP
查看IP地址
- Windows
ipconfig
- linux
ifconfig
127.0.0.1是 回环测试地址,域名为localhost,和本机通信可以用这个地址
检查网络是否正常使用ping
ping命令可以ping 域名或者ping IP
端口的介绍
端口是数据传输的通道,端口号可以标识唯一的一个端口
端口分类
- 知名端口 0-1023
80 HTTP网络传输
25 SMTP邮件传输
21 FTP文件传输 - 动态端口 1024-65535
端口和端口号一一对应
tcp的介绍
tcp英文全称:Transmission Control Protocol 简称传输控制协议,它是一种面向连接的,可靠的,基于字节的传输层通信协议
tcp通信步骤
- 创建连接
- 传输数据
- 关闭连接
tcp的特点
- 面向连接
通信双方必须先建立好连接才能进行数据的传输,数据传输完成后,双方必须断开此连接,以释放系统资源。 - 可靠传输
TCP 采用发送应答机制
超时重传
错误校验
流量控制和阻塞管理
tcp和udp的区别
socket介绍
概念:套接字(进程之间通信的工具)
作用:实现网络中多进程通信
使用场景:所有网络上的应用都要用到socket
tcp网络应用程序开发流程
tcp网络程序开发
- tcp客户端程序开发
- tcp服务器端程序开发
tcp客户端程序开发的流程
- 创建客户端socket
- 建立链接服务器端
- 发送消息
- 接收消息
- 关闭客户端socket
服务器开发的流程
- 创建服务器socket
- 绑定端口号
- 设置监听模式,返回新的套接字和IP地址及端口号
- 用新的套接字接收消息
- 用新的套接字发送消息
- 关闭新的套接字
- 关闭服务器套接字(一般不关)
tcp客户端程序开发
socket类的介绍
导入socket模块
import socket
创建客户端socket对象
socket.socket(AddressFamily, Type)
参数说明
- AddressFamily 表示IP的地址类型,分为IPv4和IPv6
- Type 表示传输协议类型
方法
- connect((host, port)) 表示和服务器连接,host是服务器的IP地址,port是应用程序的端口号
- send(data) 表示发送数据, data是二进制数据
- recv(buffersize) 表示接收数据, buffersize是每次接收数据的长度
# 1.创建客户端socket
# 2.建立链接(链接服务器)
# 3.发送数据
# 4.接收数据
# 5.关闭链接
# 导入模块
import socket
if __name__ == '__main__':
# 1.创建客户端socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.建立链接(链接服务器)
# 参数为元组类型
client_socket.connect(('192.168.32.153', 8080))
# 3.发送数据
# 要发送的数据, 将其编码为二进制文件,可以用utf-8编码
send_data = "你好呀!".encode('utf-8')
client_socket.send(send_data)
# 4.接收数据
recv_data = client_socket.recv(1024)
# 将接收的数据解码并打印
print(recv_data.decode('utf-8'))
# 5.关闭链接
client_socket.close()
tcp服务器端程序开发
socket类的介绍
导入 socket 模块
import socket
创建服务端 socket 对象
socket.socket(AddressFamily, Type)
参数说明
- AddressFamily 表示IP地址类型, 分为IPv4和IPv6
- Type 表示传输协议类型
方法说明:
- bind((host, port)) 表示绑定端口号, host 是 ip 地址,port 是端口号,ip 地址一般不指定,表示本机的任何一个ip地址都可以
- listen (backlog) 表示设置监听,backlog参数表示最大等待建立连接的个数
- accept() 表示等待接受客户端的连接请求
- send(data) 表示发送数据,data 是二进制数据
- recv(buffersize) 表示接收数据, buffersize 是每次接收数据的长度
# 导入socket模块
import socket
if __name__ == '__main__':
# 1创建客户端套接字
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.1 设置端口复用
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 2.2 绑定端口
server_socket.bind(('', 8080))
# 3设置监听模式
server_socket.listen(128)
# 4接收客户端的连接,返回新的套接字和客户端IP及端口
new_socket, client_ip_port = server_socket.accept()
print("客户端连接", client_ip_port)
# 5用新的套接字处理和客户端的通信
while True:
recv_data = new_socket.recv(1024)
if recv_data:
recv_str = recv_data.decode('utf-8')
print(recv_str)
else:
print("客户端关闭了", client_ip_port)
break
# 回复一样的消息
send_data = recv_data
new_socket.send(send_data)
new_socket.close()
一般服务器都是多任务版,可以同时处理多个客户端的收发消息,用多线程可以同时处理多个客户端的消息
# 1.创建服务器端socket
# 2.绑定端口
# 3.设置监听模式
# 4.等待客户端链接(一旦有客户端链接,会返回新的socket)
# 5.使用新的socket接收消息
# 6.使用新的socket发送消息
# 7.关闭新的socket
# 8.关闭服务器的socket
# 导入多线程模块
import threading
import socket
# 方法封装
def deal_with(new_socket, client_ip_port):
while True:
# 5.使用新的socket接收消息
recv_data = new_socket.recv(1024)
if recv_data:
print(recv_data.decode('utf-8'))
# 6.使用新的socket发送消息
send_data = '欢迎使用happy服务器'.encode('utf-8')
new_socket.send(send_data)
else:
print('客户端关闭',client_ip_port)
break
# 7.关闭新的socket
new_socket.close()
if __name__ == '__main__':
# 1.创建服务器端socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 程序结束后端口立即释放,不用再占用1-2分钟的端口
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
# 2.绑定端口(ip为空字符串, 参数为元组类型)
server_socket.bind(('', 8080))
# 3.设置监听模式
server_socket.listen(128)
while True:
# 4.等待客户端链接(一旦有客户端链接,会返回新的socket)
# accept方法会返回元组类型的数据,拆包为新的socket和IP端口
new_socket, client_ip_port = server_socket.accept()
print('新客户端连接', client_ip_port)
# 创建线程处理新的套接字实现多任务
deal_with_thread = threading.Thread(target=deal_with, args=(new_socket, client_ip_port))
# 设置为守护主线程,防止关闭不了程序
deal_with_thread.setDaemon(True)
deal_with_thread.start()
# 8.关闭服务器的socket
# server_socket.close()
下面是用网络小助手测试的结果,也可以客户端代码和服务器端的代码一起运行进行测试