python socket单线程通信
注意 socket通信默认的情况下是属于阻塞形式通信,在recv与accept函数会进行阻塞
1.客户端正常退出的情况下,server端的con的通道会正常的关闭,recv直接赋值为空
2.在windows下,使用pycharm的强制终端客户端,会造成,con通道的破坏,造成服务器端的异常(可以通过捕获异常来避免),在linux程序端,不会出现该问题
3.在发送数据的时候,send为空的情况下,在recv下,默认就是不处理,还处在阻塞的状态。 因此规定不能发送为空
4.socket通信的在py3里面,只能发送bytes类型 str-->bytes: bytes(str,"utf-8")
bytes-->str:str(bytes"utf-8")
一.基础代码
server端:
import socket
server = socket.socket()
server.bind(("127.0.0.1",6969))
server.listen() con,addr=server.accept()
while True:
data=con.recv(1024)
data_uper=str(data,"utf-8").upper()
con.send(bytes(data_uper,"utf-8"))
client端
import socket
client = socket.socket()
client.connect(('127.0.0.1',6969))
x=input(">>:")
client.send(bytes("good 你好",encoding="utf-8"))
data=client.recv(1024)
print(str(data,"utf-8"))
二.不间断聊天代码实现:
server
import socket
server = socket.socket()
server.bind(("127.0.0.1",6969))
server.listen()
while True:
con,addr=server.accept()
print(addr)
while True:
try:
data=con.recv(1024)#在程序正常退出,也就是con的tcp连接正常中断,data直接为0执行下一步
except Exception as e:
break #防止在windows下,强制关闭,con通道错误而报错,linux下不用这样
if not data:break
print(str(data,"utf8"))
x=input(">:")
con.send(bytes(x,"utf-8"))
client
import socket
client = socket.socket()
client.connect(('127.0.0.1',6969))
while True:
x=input(">>:")
if not x:continue #解决在阻塞模型下,直接回车卡住的bug
client.send(bytes(x,encoding="utf-8"))
data=client.recv(1024)
print(str(data,"utf-8"))
三.实现类似ssh的命令。实现大数据发送的基础以及粘包的问题:
在send的时候,缓存区会不断的发送数据,但是recv接受的数据大小每次都有界限。也就是说每次发送的数据过量,一次recv是接受不完的,因为调用了解决办法:
1.在发送端,先发送要发送的数据的大小
2.在接受端,通过接受的数据 与 接受的数据大小 进行比较而接入不断的接受
坑:1.int 与 bytes 不能直接转换。 2.len的大小 在str类型 与 bytes类型之间的大小是不一致的 3.在两次send直接会出现粘包的问题(通过一次recv最来解决)
粘包是因为两次send在缓存区,会一次性发送
server端
import os
import socket
server = socket.socket()
server.bind(("127.0.0.1",6969))
server.listen()
while True:
con,addr=server.accept()
print(addr)
while True:
try:
data=con.recv(1024)#在程序正常退出,也就是con的tcp连接正常中断,data直接为0执行下一步
except Exception as e:
break #防止在windows下,强制关闭,con通道错误而报错,linux下不用这样
if not data:break
cmd_line=str(data,"utf-8") cmd_result=os.popen(cmd_line,"r").read()
if not cmd_result: #当os.popen执行非系统命令时,返回值为空
cmd_result = "未知命令"
cmd_result=bytes(cmd_result,"utf-8")
cmd_result_len=bytes(str(len(cmd_result)),"utf-8")
#int与bytes之间不能直接转换。
#len 在str与bytes类型之间的长度是不一致的!!!
print("发送数据长度",str(cmd_result_len,"utf-8")) con.send(cmd_result_len)
flag=con.recv(1024) #通过一次recv来解决两个send之间粘包的问题。
con.send(cmd_result)
clinet端
import socket
client = socket.socket()
client.connect(('127.0.0.1',6969))
while True:
x=input(">>:")
if not x:continue
client.send(bytes(x,encoding="utf-8"))
recv_len=int(str(client.recv(1024),"utf-8"))
client.send(bytes("ok","utf-8"))
print(recv_len)
data=bytes()
while len(data) != recv_len:
data += client.recv(1024)
print(str(data,"utf-8"))
四、实现文件下载:
在python中数据都是bytes类型,打开文件 以rb,wb的类型打开。
1.在服务方:
通过os模块,读取文件的大小,使用f.read(size)读取指定数量,通过该大小来循环发送数据
2.在客户端
先接受数据的大小,通过已经接受的数据 与 文件大小来判断大小
服务器端
import os
import socket
server = socket.socket()
server.bind(("127.0.0.1",6969))
server.listen() while True:
con,addr = server.accept()
while True:
cmd=str(con.recv(1024),"utf-8")
print(cmd)
cmd = cmd.split()
if cmd[0] == "push":
print(cmd[0])
f = open(cmd[1], "rb")
file_size = os.stat(cmd[1]).st_size
print(file_size)
con.send(bytes(str(file_size), encoding="utf-8")) flag=con.recv(1024)
# for line in f:
# con.send(line)
data_size=0
while file_size != data_size:
data=f.read(1024)
con.send(data)
data_size += len(data)
print(data_size)
print("发送完毕") f.close()
客户端
import socket
import os
client = socket.socket()
client.connect(("127.0.0.1",6969)) while True:
cmd=bytes(input("->:"),"utf8")
client.send(cmd) file_size = int(str(client.recv(1024), "utf-8"))
client.send("ok".encode("utf-8"))
data_len = 0
f = open("1.new.avi","wb")
while file_size != data_len:
data = client.recv(1024)
data_len += len(data)
f.write(data)
print(data_len)
f.close()
五、多client并发连接 sockserver
创建sockserver四大步骤:
- First, you must create a request handler class by subclassing the
BaseRequestHandlerclass and overriding itshandle()method; this method will process incoming requests. - Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
- Then call the
handle_request()orserve_forever()method of the server object to process one or many requests. - Finally, call
server_close()to close the socket.
import socketserver class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server. It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
""" def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper()) if __name__ == "__main__":
HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
这里还不能直接使用:
我们调用多线程的类 就可以使用了
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
python socket单线程通信的更多相关文章
- Python Socket单线程+阻塞模式
Python之旅]第五篇(二):Python Socket单线程+阻塞模式 python Socket单线程 Socket阻塞模式 串行发送 摘要: 前面第五篇(一)中的一个Socket例子其实就是 ...
- Python socket (单线程)
client, 客户端 code : 客户端主要方法, s.send(); s.sendall(); s.recv(); s.connect() class Client(object): def _ ...
- python - socket通信笔记
参考: 通过编写聊天程序来熟悉python中多线程和socket的用法:https://www.cnblogs.com/mingjiatang/p/4905395.html python socket ...
- Python Socket通信原理
[Python之旅]第五篇(一):Python Socket通信原理 python Socket 通信理论 socket例子 摘要: 只要和网络服务涉及的,就离不开Socket以及Socket编 ...
- Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信
Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...
- 第五十三节,socket模块介绍,socket单线程通讯
socket单线程通讯,只能单线程通讯,不能并发 socket是基于(TCP.UDP.IP)的通讯.也叫做套接字 通讯过程由服务端的socket处理信息发送,由客户端的socket处理信息接收. so ...
- python socket编程 实现简单p2p聊天程序
目标是写一个python的p2p聊天的项目,这里先说一下python socket的基础课程 一.Python Socket 基础课程 Socket就是套接字,作为BSD UNIX的进程通信机制,取后 ...
- 一小时学会用Python Socket 开发可并发的FTP服务器!!
socket是什么 什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求 ...
- Python Socket 编程——聊天室示例程序
上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...
随机推荐
- 网络端口地址转换的NAPT配置
背景:只有一个IP地址,实现内网内多台主机访问外网 原理:NAPT使用不同的端口来映射对各内网的IP地址到一个指定的外网IP地址,多对一. NAPT采用端口多路复用的方式.内部网络的所有主机均可共享一 ...
- 【Java学习笔记之十五】Java中的static关键字解析
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
- C++课程设计类作业2
不要问我一个晚上在干啥,就写写这种烦到极点的类,啰嗦! #include <bits/stdc++.h> using namespace std; class complexed { pu ...
- [bzoj2333] [SCOI2011]棘手的操作 (可并堆)
//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景... Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1 ...
- JAVA虚拟机之对象探秘
上一章主要写到了JVM中运行时数据区域各个部分的功能及其作用.上一章说到了对象是分配在堆上面的,所以接下来我们写到对象在堆内存中是如何创建.如何布局.如何访问.1. 对象的创建 在java程序中对象的 ...
- Python 3 利用 Dlib 19.7 实现人脸识别和剪切
0.引言 利用python开发,借助Dlib库进行人脸识别,然后将检测到的人脸剪切下来,依次排序显示在新的图像上: 实现的效果如下图所示,将图1原图中的6张人脸检测出来,然后剪切下来,在图像窗口中依次 ...
- 《You dont know JS》类型篇总结
类型 javaScript中的类型和熟知的一些强类型语言的有关类型的定义是不一样的.在js中,类型的含义是值的内部特征,它定义了值得行为,以使其区别于其他值.(a type is an intrins ...
- 字符串API
string可以看成是多个字符组成的只读数组,也可以通过下标去访问某个字符 访问i位置的字符 : str[i] 字符个数: str.length 倒数第n个字符 : str[str.length- ...
- 数据库复习总结(2)-SQLServer的管理
1.需要安装SQLServer2008或者SQLServer2012,若要使用SQLServer管理工具进行开发还要安装SQL Server Management Studio,还可以使用Visual ...
- 如何开发由Create-React-App 引导的应用(四)
此文章是翻译How to develop apps bootstrapped with Create React App 官方文档 系列文章 如何开发由Create-React-App 引导的应用 如 ...