Socket 是一种用于实现网络通信的编程接口,它允许不同计算机之间通过网络进行数据交换。在计算机网络编程中,Socket 被广泛应用于客户端-服务器通信和进程间通信等场景。下面是关于 Socket 的一些重要信息:
Socket 是什么:
Socket 的类型:
Socket 编程:
socket 模块进行 Socket 编程。Socket 通信流程:
Socket 应用:
总的来说,Socket 是一种重要的网络编程接口,通过 Socket 可以实现不同计算机之间的数据传输和通信,为构建各种网络应用提供了基础。在 Python 中,通过内置的 socket 模块,可以方便地进行 Socket 编程。
建立服务端Socket对象:
socket 模块创建一个服务端的 Socket 对象,指定使用 TCP 协议。绑定IP地址和端口号:
bind() 方法将服务端的 Socket 对象绑定到指定的IP地址和端口号上。设置监听模式:
listen() 方法设置 Socket 对象为监听模式,指定最大连接数。等待客户端连接:
accept() 方法等待客户端的连接请求,一旦有客户端连接,会返回一个新的 Socket 对象和客户端的地址信息。接收客户端数据/给客户端发送信息:
recv() 方法接收客户端发送的数据,使用 send() 方法发送数据给客户端。关闭连接:
创建客户端Socket对象:
socket 模块创建一个客户端的 Socket 对象,同样指定使用 TCP 协议。连接服务端IP和端口:
connect() 方法连接到服务端指定的IP地址和端口号。接收服务端数据/发送客户端数据:
recv() 方法接收服务端发送的数据,使用 send() 方法发送数据给服务端。关闭连接:
下面是一个简单的示例代码,演示了服务端和客户端之间的简单通信过程:
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() 服务端:
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() 网页响应数据需要遵守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