文章目录
一、socket_TCP网络通信
Socket 是一种用于实现网络通信的编程接口,它允许不同计算机之间通过网络进行数据交换。在计算机网络编程中,Socket 被广泛应用于客户端-服务器通信和进程间通信等场景。下面是关于 Socket 的一些重要信息:
Socket 是什么:
- Socket 是一种抽象的通信端点,可以用于在不同计算机之间进行数据传输。
- 在网络编程中,Socket 通常由 IP 地址和端口号组成,用于唯一标识网络中的通信实体。
Socket 的类型:
- 在 Python 中,常用的 Socket 类型有两种:TCP Socket 和 UDP Socket。
- TCP Socket 提供面向连接的、可靠的数据传输,适用于要求数据完整性的场景。
- UDP Socket 提供无连接、不可靠的数据传输,适用于要求速度和效率的场景。
Socket 编程:
- 在 Python 中,可以使用内置的
socket
模块进行 Socket 编程。 - 通过创建 Socket 对象并调用其方法,可以实现网络通信的各种操作,如建立连接、发送数据、接收数据等。
- 在 Python 中,可以使用内置的
Socket 通信流程:
- 在客户端-服务器通信中,通常的流程是:服务器创建 Socket 并绑定到指定的 IP 地址和端口,然后监听连接;客户端创建 Socket 并连接到服务器指定的 IP 地址和端口;双方建立连接后进行数据交换。
Socket 应用:
- Socket 在网络编程中广泛应用于各种场景,如 Web 服务器、聊天应用、远程控制、文件传输等。
- 通过 Socket,可以实现不同计算机之间的实时通信和数据交换,为网络应用提供了基础支持。
总的来说,Socket 是一种重要的网络编程接口,通过 Socket 可以实现不同计算机之间的数据传输和通信,为构建各种网络应用提供了基础。在 Python 中,通过内置的 socket
模块,可以方便地进行 Socket 编程。
1.如何实现发信息的网络通信
- 硬件接口
- 发送信息
- 接受信息
- 关机
2.通信步骤
- 连接
- 传输信息
- 关闭链接
3.Python实现步骤
服务端实现步骤
建立服务端Socket对象:
- 使用
socket
模块创建一个服务端的 Socket 对象,指定使用 TCP 协议。
- 使用
绑定IP地址和端口号:
- 使用
bind()
方法将服务端的 Socket 对象绑定到指定的IP地址和端口号上。
- 使用
设置监听模式:
- 使用
listen()
方法设置 Socket 对象为监听模式,指定最大连接数。
- 使用
等待客户端连接:
- 使用
accept()
方法等待客户端的连接请求,一旦有客户端连接,会返回一个新的 Socket 对象和客户端的地址信息。
- 使用
接收客户端数据/给客户端发送信息:
- 使用新的 Socket 对象进行数据的接收和发送,可以使用
recv()
方法接收客户端发送的数据,使用send()
方法发送数据给客户端。
- 使用新的 Socket 对象进行数据的接收和发送,可以使用
关闭连接:
- 在通信结束后,关闭服务端的 Socket 对象。
客户端实现步骤
创建客户端Socket对象:
- 使用
socket
模块创建一个客户端的 Socket 对象,同样指定使用 TCP 协议。
- 使用
连接服务端IP和端口:
- 使用
connect()
方法连接到服务端指定的IP地址和端口号。
- 使用
接收服务端数据/发送客户端数据:
- 使用客户端 Socket 对象进行数据的接收和发送,可以使用
recv()
方法接收服务端发送的数据,使用send()
方法发送数据给服务端。
- 使用客户端 Socket 对象进行数据的接收和发送,可以使用
关闭连接:
- 在通信结束后,关闭客户端的 Socket 对象。
示例代码
下面是一个简单的示例代码,演示了服务端和客户端之间的简单通信过程:
server_socket.py
# 服务端代码 import socket """ 套接字类: socket.socket : 这个就是我们的套接字类,里面有两个参数 socket_family : 网络地址类型:ipv4参数值 ==> AF_INET ipv6参数值 ===》 AF_INET6 socket_type: 套接字:TCP协议 ==> SOCK_STREAM UDP协议 ==> SOCK_DGRAM """ #1.建立服务端对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#表示IPV4地址族通信使用TCP #2.绑定IP地址和端口号 server_socket.bind(('localhost', 9999)) #3.设置监听数 server_socket.listen(5)#设置监听数为5 print("等待客户端连接...") """ accept: 这个方法调用后会有两个返回值 1.客户端对象(数据),我们以后都要用这个对象进行接受和发送 2.链接客户端的ip,端口号 """ #4.等待客户端连接 client_socket, address = server_socket.accept() print(f"连接来自:{address}") #5.接收客户端数据/给客户端发送信息 data = client_socket.recv(1024)#1024是设置的最大字节数,单位是b print(f"收到客户端消息:{data.decode('utf-8')}") ## 数字流转换为文档格式字符串 #给客户端发送信息 client_socket.send("Hello, client!".encode()) # 6.关闭链接 client_socket.close() server_socket.close()
client_socket.py
# 客户端代码 import socket #1.创建客户端Socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #2.连接服务端IP和端口 client_socket.connect(('localhost', 9999)) #3.接收服务端数据/发送客户端数据 client_socket.send("Hello, server!".encode()) # 网络只允许二进制传输,需要encode编译 # encode : 字符串转换为数据流 # decode : 数据流转为字符串 data = client_socket.recv(1024) print(f"收到服务端消息:{data.decode()}") client_socket.close()
循环通信
server_socket.py
# 服务端代码 import socket server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 9999)) server_socket.listen(5) print("等待客户端连接...") client_socket, address = server_socket.accept() print(f"连接来自:{address}") while 1: try: data = client_socket.recv(1024) print(data.decode("utf-8")) msg = input(">>>") client_socket.send(msg.encode("utf-8")) except ConnectionResetError: break client_socket.close() server_socket.close()
client_socket.py
import socket client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 9999)) while 1: msg = input(">>>") client_socket.send(msg.encode("utf-8")) if msg == "再见": break if not msg: continue data = client_socket.recv(1024) print(data.decode("utf-8")) client_socket.close()
二、socket_UDP网络通信
服务端:
1.创建服务端socket对象
2.绑定自己的ip和端口号
3.接受客户端数据/发送数据
4.关闭链接
socket --> bind —> recvfrom(收)/sendto(发) —>close
客户端
1.创建客户端socket对象
2.发送数据,接受数据
3.关闭
server.py
import socket """ 套接字类: socket.socket : 这个就是我们的套接字类,里面有两个参数 socket_family : 网络地址类型:ipv4参数值 ==> AF_INET ipv6参数值 ===》 AF_INET6 socket_type: 套接字:TCP协议 ==> SOCK_STREAM UDP协议 ==> SOCK_DGRAM """ # 创建套接字对象 # IPhone 就是ipv4,UDP协议的套接字对象 IPhone = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定ip和端口号 # 我们的bind参数只有一个实参,这里只能用元组传输 IPhone.bind(("localhost", 10086)) # 5.接受和发送 # 接收数据:设定最大字节数,单位为b while 1: try: """ 接受数据:也要最大字节数 recvfrom:这个方法也是有两个返回值 1.客户端套接字对象 2.客户端ip和端口号 """ data, adder = IPhone.recvfrom(1024) print(data.decode("utf-8")) msg = input(">>>") # 发送信息 IPhone.sendto(msg.encode("utf-8"), adder) except ConnectionResetError: break # 6.关闭链接 IPhone.close()
client.py
import socket # 建立客户端的对象 client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建一个元组 ipPort = ("127.0.0.1", 10086) # 网络只允许二进制传输,需要encode编译 # encode : 字符串转换为数据流 # decode : 数据流转为字符串 while 1: msg = input(">>>") if msg == "拜拜": break if not msg: continue client.sendto(msg.encode("utf-8"), ipPort) # udp 有一个要求,每一次通讯都要对方的IP地址和端口号 data, adder = client.recvfrom(1024) print(data.decode("utf-8")) # 4.关闭 client.close()
三、UDP和TCP的比较
1.UDP的优点
- 低延迟: UDP是面向无连接的协议,不需要建立连接和维护状态,因此通信过程中的延迟较低。
- 高效性: UDP不进行数据重传、流量控制等额外处理,简单高效,适用于实时性要求较高的场景。
- 无拥塞控制: UDP不进行拥塞控制,不会因为网络拥塞而调整传输速率,适用于一些特定场景。
- 适用于广播和多播: UDP支持广播和多播,可以实现一对多的通信。
2.TCP的优点
- 可靠性: TCP提供数据重传、流量控制、拥塞控制等机制,保证数据的可靠传输。
- 顺序性: TCP保证数据包按照发送顺序到达接收端,不会出现数据包乱序的情况。
- 错误校正: TCP提供校验和机制,可以检测数据传输过程中的错误,保证数据的完整性。
- 流量控制: TCP通过滑动窗口机制进行流量控制,避免发送方发送速度过快导致接收方无法处理。
四、socket响应网页(了解)
网页响应数据需要遵守http协议
如果不遵守就无法识别任何响应信息
那么http协议需要你自己编写格式
客户端接受数据:
数据响应格式:
1.响应行(表示http版本 HTTP1.1, 响应状态码)200 表示响应成功
2.响应头(一大堆键值对) 可写可不写
3.\r\n (空白行,每一个响应数据都要用\r\n结束)
4.响应体(需要返回给浏览器看的数据)
1.响应行:HTTP响应报文中的第一行,用于表示服务器对客户端请求的响应状态。响应行通常由三部分组成:HTTP协议版本、状态码和状态码的文本描述。
2.响应头:用于传输关于响应的元数据信息,如服务器类型、日期时间等。
3.响应体包含实际的响应数据,通常是HTML、文本、图片等内容。
请求格式:
1.请求首行(表示http版本,数据请求方法)
2.请求头 可写可不写
3.请求体
静态服务器
server.py
import socket if __name__ == '__main__': tcpServerSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置端口复用(循环使用),程序退出里面关闭该端口号 tcpServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # "" 这个可以不写,直接空字符,默认是本机地址 tcpServerSocket.bind( ("", 8848) ) tcpServerSocket.listen(128) while 1: try: newSocket, adder = tcpServerSocket.accept() data = newSocket.recv(4096) # 打印请求信息 print(data) # 返回一个html前端页面 with open(r"xyz.html", "r", encoding="utf-8") as f: fileData = f.read() #响应行 #http/1.1 是http协议版本, 200 ok 是状态码和说明信息 responseLine = "HTTP/1.0 200 ok \r\n" # 响应头 responseHeader = "server: xyzfuwuqi/1.0 \r\n" # 响应体 数据包 responseBody = fileData # 把上面的报文统一组装在一起 response = responseLine+responseHeader+"\r\n" + responseBody # 转化数据流 responseData = response.encode("utf-8") newSocket.send(responseData) newSocket.close() except Exception as e: print(e) break