一、IP地址的介绍
1.1 IP地址
windows和Linux查看网卡信息
- Linux中 ifconfig
- windows中 ipconfig
1.1.1 IP地址的分类:
1.2 端口
1.2.1 端口分类
1.知名端口(well known ports):
- 80端口分配给HTTP服务
- 21端口分配给FTP服务
- 范围是从0到1023
2.动态端口:
- 动态端口的范围是从1024-65535
二、socket简介
- TCP/IP协议:TCP/IP协议是Transmission Control Protocol/Internet Protocol的简写,即传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。
- TCP/IP: 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
1. socket
socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。白话说,socket就是两个节点为了互相通信,而在各自家里装的一部’电话’。
socket的使用
- 创建套接字
- 使用套接字收/发数据
- 关闭套接字
2.创建套接字
import socket
# from socket import socket
# 1、创建套接字
'''
协议族:family = AF_INET, AF_INET是ipv4 AF_INET6是ipv6
套接字类型:type = SOCK_STREAM, TCP 流式套接字 UDP SOCK_STREAM数据报套接字
AF_INET = 2
AF_INET6 = 23
'''
s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 2、使用套接字 收/发 数据
# 3、关闭套接字
s.close()
3.1 udp发送与接收程序
"""
UDP发送数据
"""
import socket
''''
1、UDP发送数据
'''
def main():
# 创建一个UDP套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 发送数据
# encode是转码
# windows 编码是GBK
# Ubantu 是UTF-8
send_data = 'CSY is SB 哈哈哈哈,陈思能够与'
udp_socket.sendto(send_data.encode('gbk'), ('192.168.1.6', 8897))
# udp_socket.sendto(b'CSY is CQ', ('192.168.1.6', 8897))
# 关闭连接
udp_socket.close()
''''
2、UDP循环发送数据
'''
def main1():
while True:
send_data = input('输入你想发送的数据:')
if send_data == '':
break
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.sendto(send_data.encode('gbk'), ('192.168.1.6', 8897))
udp_socket.close()
if __name__ == '__main__':
# main()
main1()
UDP接收数据
1 创建套接字
2 绑定本地信息(IP和端口)
3 接受数据
4 打印数据
5 关闭套接字
'''
UDP接收数据
1 创建套接字
2 绑定本地信息(IP和端口)
3 接受数据
4 打印数据
5 关闭套接字
'''
import socket
def main():
# 1 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 2 绑定本地信息(IP和端口)
bind_addr = ('', 57736)
udp_socket.bind(bind_addr)
while True:
# 3 接受数据
# 1024 表示本次接收的最大字节数
recv_data = udp_socket.recvfrom(1024)
# 元组 接收倒的数据 (发送方的ip , 端口)
# (b'1', ('192.168.1.6', 8897))
# 4 打印数据
recv = recv_data[0]
send_data = recv_data[1]
print('发送的ip地址:{},发送的信息:{}'.format(str(send_data), recv.decode('gbk')))
# 5 关闭套接字
udp_socket.close()
if __name__ == '__main__':
main()
3.2 UDP聊天器
udp聊天器
- 创建套接字 套接字是可以同时收发数据的
- 发送数据
- 接收数据
'''
聊天器
'''
import socket
def send_data(udp_socket):
"""发送数据"""
send_data = input('请输入要发送的数据:')
dest_ip = input('请输入要发送的IP:')
dest_port = int(input('请输入要发送的端口:'))
udp_socket.sendto(send_data.encode('gbk'), (dest_ip, dest_port))
def recv_data(udp_socket):
"""接收数据"""
recv_data = udp_socket.recvfrom(1024)
print("%s:%s" % (recv_data[1], recv_data[0].decode('gbk')))
def main():
# 创建套接字 同时接收发送数据
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定
udp_socket.bind(("", 7788))
while True:
# 发送
send_data(udp_socket)
# 接收
recv_data(udp_socket)
# udp_socket.close()
if __name__ == '__main__':
main()
4.1 TCP介绍
- CP协议,传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议
- TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
- TCP通信模型中,在通信开始之前,一定要先建立相关连接,才能发生数据。
4.2 TCP特点
- 面向连接
- 通信双方必须先建立连接才能进行数据的传输
- 可靠传输
- TCP采用发送应答机制
- 超时重传
- 错误校验
- 流量控制和阻塞管理
TCP通信
4.3 TCP客户端构建
TCP客户端构建流程
- 1.创建socket
- 2.链接服务器
- 3.接收数据(最大接收2014个字节)
- 4.关闭套接字
'''
TCP客户端构建流程
1.创建socket
2.链接服务器
3.接收数据(最大接收1024个字节)
4.关闭套接字
'''
import socket
# from socket import socket
def main():
# 创建TCP套接字
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.链接服务器
server_ip = '192.168.1.6'
server_port = int(7891)
tcp_client.connect((server_ip, server_port))
# 3.1 发送数据
send_data = input('发送的数据:')
tcp_client.send(send_data.encode('gbk'))
# 3.2 接收数据(最大接收1024个字节)
# 阻塞
recvdata = tcp_client.recv(1024)
print(recvdata.decode('gbk'))
# 4.关闭套接字
tcp_client.close()
if __name__ == '__main__':
main()
4.3.1 TCP服务端
- socket创建套接字
- List item
- bind绑定IP和port
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接收发送数据
- 关闭套接字
'''
TCP服务端
1 socket:创建套接字
2 bind:绑定IP和port
3 listen:使套接字变为可以被动链接
4 accept:等待客户端的链接
5 recv/send:接收发送数据
'''
import socket
def main():
# 1. TCp 套接字
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定
tcp_server.bind(('192.168.1.6', 7890))
# 3. listen:使套接字变为可以被动链接
tcp_server.listen(128)
# 4. accept:等待客户端的链接
"""
accept() -> (socket object, address info)
socket object 是 新生成的套接字
address info 是 客户端地址
"""
new_client_socket, client_addr = tcp_server.accept()
# 5 recv/send:接收发送数据
# 5.1 recv:接收数据
recv_data = new_client_socket.recv(1024)
print(recv_data.decode('gbk'))
# 5.2 send:发送数据
# send_data = input('发送的数据:')
new_client_socket.send('这是发送的数据'.encode('gbk'))
# 关闭套接字
new_client_socket.close()
tcp_server.close()
if __name__ == '__main__':
main()
4.3.2 TCP服务端为多个客户端服务
import socket
def main():
# 1. TCp 套接字
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定
tcp_server.bind(('192.168.1.6', 7890))
# 为多个客户端服务
while True:
# 3. listen:使套接字变为可以被动链接
tcp_server.listen(128)
# 4. accept:等待客户端的链接
"""
accept() -> (socket object, address info)
socket object 是 新生成的套接字
address info 是 客户端地址
"""
new_client_socket, client_addr = tcp_server.accept()
# 5 recv/send:接收发送数据
# 5.1 recv:接收数据
# 为一个客户端多次服务
while True:
recv_data = new_client_socket.recv(1024)
# print(recv_data.decode('gbk'))
# 5.2 send:发送数据
# send_data = input('发送的数据:')
if recv_data.decode('gbk'):
new_client_socket.send('这是发送的数据'.encode('gbk'))
else:
break
# 关闭客户端
new_client_socket.close()
tcp_server.close()
if __name__ == '__main__':
main()
一个服务端多个客户端服务:
第一个客户端断开连接后,第二个客户端才回收到服务端发送的数据
5. 文件下载器
先启动服务器,再启动客户端,不然会报错。
5.1 文件下载器——客户端
'''
TCP文件下载客户端
1、创建套接字
2、连接服务器
3、要下载的文件名称
4、发送下载文件的请求
5、接收服务器发送过来的数据
6、保存文件
7、关闭套接字
'''
import socket
def main():
# 1、创建套接字
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、连接服务器
server_ip = '192.168.1.6'
server_port = 7890
tcp_client_socket.connect((server_ip, server_port))
# 3、要下载的文件名称
flie_name = input('输入要下载文件的名称:')
# 4、发送下载文件的请求
tcp_client_socket.send(flie_name.encode('gbk'))
# 5、接收服务器发送过来的数据
recv_data = tcp_client_socket.recv(1024*1024)
# 6、保存文件
# wb 读写
with open('接收'+flie_name, 'wb') as f:
f.write(recv_data)
# 7、关闭套接字
tcp_client_socket.close()
if __name__ == '__main__':
main()
5.2 文件下载器——服务端
'''
TCP文件下载-服务端
1、创建套接字
2、绑定信息
3、listen主动变被动
4、accept 等待客户端的连接
5、发送/接收数据
6、关闭套接字
'''
import socket
def send_file_client(new_client_socket):
# 接收客户端发送过来的数据
file_name = new_client_socket.recv(1024).decode()
content = b''
try:
with open(file_name, 'rb') as f:
content = f.read()
except Exception as e:
print('【%s】文件不存在' % file_name)
new_client_socket.send(content)
new_client_socket.close()
def main():
# 1、创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2、绑定信息
tcp_server_socket.bind(('192.168.1.6', 7890))
# 3、listen 主动变被动
tcp_server_socket.listen(128)
# 4、accept 等待客户端的连接
new_client_socket, client_addr = tcp_server_socket.accept()
# 5、给客户端返回文件内容
send_file_client(new_client_socket)
# 6、关闭套接字
tcp_server_socket.close()
if __name__ == '__main__':
main()
六、TCP与UDP区别总结
1、TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP对系统资源要求较多,UDP对系统资源要求较少。