一、简单socket示例
- 服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #AF_INET: ipv4, SOCK_STREAM: TCP
phone.bind(("127.0.0.1", 8888,))
phone.listen(5) #可以同时接受5个连接
conn,addr = phone.accept() #conn:连接,addr:对方ip地址
# print(conn,addr)
msg = conn.recv(1024) #接收1024个字节的信息
print("对方发来的消息:",msg.decode("utf-8"))
conn.send(msg.upper()) #发送
conn.close()
phone.close()
- 客户端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8888,))
phone.send("hello".encode("utf-8"))
msg = phone.recv(1024)
print("服务端发来的消息:",msg.decode("utf-8"))
二、循环收发
- 服务端
from socket import *
ip_port = ('127.0.0.1', 8888,)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
print("服务端启动 ...")
conn,addr = tcp_server.accept()
print("双向连接", conn)
print("客户端地址", addr)
while True:
data = conn.recv(buffer_size)
print("客户端发来的消息:",data.decode("utf-8"))
conn.send(data.upper())
conn.close()
tcp_server.close()
- 客户端
from socket import *
ip_port = ('127.0.0.1', 8888,)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
msg = input(">>: ").strip()
if not msg:continue #判断输入的信息是否为空
tcp_client.send(msg.encode("utf-8"))
print("已经发送成功!")
data = tcp_client.recv(buffer_size)
print("服务器发送来的消息:",data.decode("utf-8"))
tcp_client.close()
三、循环提供服务(多客户端串行)
- 服务端
from socket import *
ip_port = ('127.0.0.1', 8888,)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #重新使用套接字和地址,防止发生tcp连接未断开情况
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
print("服务端启动 ...")
while True:
conn,addr = tcp_server.accept()
print("双向连接", conn)
print("客户端地址", addr)
while True:
try:
data = conn.recv(buffer_size)
if not data:break #防止客户端端口一只收空
print("客户端发来的消息:",data.decode("utf-8"))
conn.send(data.upper())
except Exception:
break
conn.close()
tcp_server.close()
- 客户端
from socket import *
ip_port = ('127.0.0.1', 8888,)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
msg = input(">>: ").strip()
if not msg:continue #判断输入的信息是否为空
tcp_client.send(msg.encode("utf-8"))
print("已经发送成功!")
data = tcp_client.recv(buffer_size)
print("服务器发送来的消息:",data.decode("utf-8"))
tcp_client.close()
四、udp协议的socket编程(ntp服务)
- 服务端
from socket import *
import time
ip_port = ('127.0.0.1', 8889,)
buffer_size = 1024
udp_server = socket(AF_INET,SOCK_DGRAM) #SOCK_DGRAM: 数据报式的套接字,udp
udp_server.bind(ip_port)
while True:
data, addr = udp_server.recvfrom(buffer_size)
print(data.decode("utf-8"))
back_time = time.strftime('%Y-%m-%d %X')
udp_server.sendto(back_time.encode("utf-8"),addr)
- 客户端
from socket import *
ip_port = ('127.0.0.1', 8889,)
buffer_size = 1024
udp_clinet = socket(AF_INET,SOCK_DGRAM)
while True:
msg = input(">>: ").strip()
udp_clinet.sendto(msg.encode("utf-8"), ip_port)
data,addr = udp_clinet.recvfrom(buffer_size)
print("服务器当前时间:",data.decode("utf-8"))
五、基于tcp的ssh服务
- 服务端
from socket import *
import subprocess
import struct
ip_port = ("127.0.0.1", 8888,)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
conn,addr = tcp_server.accept()
print("新客户端连接:", addr)
while True:
try:
cmd = conn.recv(buffer_size)
if not cmd:break
print("收到客户端的命令:", cmd)
res = subprocess.Popen(cmd.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
err = res.stderr.read()
if err:
cmd_res = err
else:
cmd_res = res.stdout.read()
if not cmd_res:
cmd_res = "执行成功".encode("gbk")
#解决粘包问题
length = len(cmd_res)
data_length = struct.pack('i',length) #将数字转换为byte类型
conn.send(data_length)
conn.send(cmd_res)
except Exception as e:
print(e)
break
conn.close()
- 客户端
from socket import *
import struct
from functools import partial
ip_port = ("127.0.0.1", 8888,)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
cmd = input(">>: ").strip()
if not cmd:continue
if cmd == "quit":break
tcp_client.send(cmd.encode("utf-8"))
#解决粘包
length_data = tcp_client.recv(4)
length = struct.unpack('i',length_data)[0]
recv_size = 0
recv_msg = b''
while recv_size < length:
recv_msg += tcp_client.recv(buffer_size)
recv_size = len(recv_msg)
# for i in iter(partial(tcp_client.recv,buffer_size), b''):
# recv_msg += i
print(recv_msg.decode("gbk"))
tcp_client.close()
六、socketserver模块
- server类:处理连接
- BaseServer
- TCPServer
- UnixStreamServer
- UDPServer
- UnixDatagramServer
- request类:处理通信
- BaseRequestHandler
- StreamRequestHandler
- DatagramRequestHandler
- 服务端
import socketserver
class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print(self.request) #conn
print(self.client_address) #addr
while True:
try:
data = self.request.recv(1024)
if not data:break
print("收到客户端的消息:",data)
self.request.sendall(data.upper())
except Exception:
break
if __name__ == '__main__':
tcp_server = socketserver.ThreadingTCPServer(('127.0.0.1',8888),MyServer) #多线程的tcp server
tcp_server.serve_forever()
- 客户端
from socket import *
ip_port = ("127.0.0.1", 8888,)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
msg = input(">>: ").strip()
if not msg:continue
if msg == "quit":break
tcp_client.send(msg.encode("utf-8"))
data = tcp_client.recv(buffer_size)
print(data.decode("utf-8"))
ftp代码:https://files.cnblogs.com/files/L-dongf/python_ftp.zip