1. TCP:
client:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
import random
#实例初始化
client = socket.socket()
#访问的服务器端ip和端口
ip_port = ("127.0.0.1",8888)
#连接主机
client.connect(ip_port)
#定义一个循环,不断发送和接收消息
while True:
# 接收主机信息
data = client.recv(1024)
# 打印接收信息
# 此处的byte型数据特指python3.x以上
print(data.decode())
#输入发送的信息
msg_input = input("请输入发送的消息")
#消息发送
client.send(msg_input.encode())
if msg_input == "exit":
break
data = client.recv(1024)
print(data.decode())
Server:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import socket
import random
#创建实例
fd = socket.socket()
# 定义绑定ip和port
ip_port = ("127.0.0.1",8888)
#绑定监听
fd.bind(ip_port)
#最大连接数()
fd.listen(5)
while True:
#提示信息
print("正在进行等待接收数据....")
#接收数据
conn,address = fd.accept()
#定义信息
msg = "连接成功!"
#返回信息
#python3.x以上,网络数据的接收发送都是byte类型
#如果发送的数据是str型的则需要进行编码
conn.send(msg.encode())
#不断的接收客户端发来的信息
while True:
#接收客户端发来的信息
data = conn.recv(1024)
print(data.decode())
#接收到退出指令
if data == b'exit':
break
#处理客户端数据
conn.send(data)
# 发送随机信息
conn.send(str(random.randint(1,100)).encode())
#主动关闭连接
conn.close()
2. UDP:
UDP与TCP还有的不同点除了不是三次握手安全连接外,UDP的通信方式是可以支持多次数据发送,以及多客户端的连接,原因是UDP通信连接并不需要建立一个可靠的通信通道。
Client:
import socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port = ("127.0.0.1",8888)
while True:
msg_input = input("请输入发送的消息:")
if msg_input == "exit":
break
sk.sendto(msg_input.encode(),ip_port) #注意:使用sendto,而不是send
#客户端不进行连接后,服务器端会关闭通信端口。
#为了资源有效利用,直接关闭实例
sk.close()
Server:
import socket
sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port = ("127.0.0.1",8888)
sk.bind(ip_port)
while True:
data = sk.recv(1024)
print(data.decode())
3. Socket 的非阻塞(实现多个client连接server)
Server端:
import socketserver #与socekt的区别是,导入了threading模块,支持多线程
import random
#定义一个类
class MyServer(socketserver.BaseRequestHandler):
#如果handle出现报错,则会直接跳过
#setup方法和finish方法无论如何都会继续执行
#首先执行setup
def setup(self):
pass
#然后执行handle
def handle(self):
conn = self.request
msg = "Hello World!"
conn.send(msg.encode())
while True:
data = conn.recv(1024)
print(data.decode())
if data == b'exit':
break
conn.send(str(random.randint(1,1000)).encode())
conn.close()
#最后执行finish
def finish(self):
pass
if __name__ == "__main__":
#创建多线程的实例
server = socketserver.ThreadingTCPServer(("127.0.0.1",8888),MyServer)
#开启异步多线程,等待客户端连接
server.serve_forever()
4.文件上传
send端(上传文件):
#作为客户端
import socket
sk = socket.socket()
#定义连接ip和port
ip_port = ("127.0.0.1",9999)
#连接服务器
sk.connect(ip_port)
#文件上传
#打开文件
with open('socket_server_tcp2.py','rb') as f: #rb-->二进制模式只读
#按每一段分割文件
for i in f:
#数据上传
sk.send(i) #文件打开就是byte类型,所以不用字符编码
#等待接收完成标志
data = sk.recv(1024)
if data != b"success":
break
#给服务器端发送结束信号
sk.send('quit'.encode())
Recv端(接收文件):
#作为服务端
#导入模块
import socket
sk = socket.socket()
ip_port = ("127.0.0.1",9999)
sk.bind(ip_port)
sk.listen(5)
while True:
#等待客户端连接
conn, address = sk.accept()
#一直使用当前连接进行数据接收,直到标志出现
while True:
#打开文件等待数据写入
with open("file.txt","ab") as f: #二进制模式读写兼备,末尾写入
data = conn.recv(1024)
if data ==b"quit":
break
#写入文件
f.write(data)
#接收完成标志
print("success")
conn.send("success".encode())
#打印提示信息
print("文件打印接收完成!")
#关闭连接
sk.close()
Noted:这里涉及到while... as...的用法。
主要点记录: