注意 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四大步骤:

  1. First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests.   
  2. Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.
  3. Then call the handle_request() orserve_forever() method of the server object to process one or many requests.
  4. 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)

最新文章

  1. 关于python的10个建议,比较适合新手吧.
  2. web应用中使用JavaMail发送邮件
  3. PHP面向对象_重载新的方法(parent::)
  4. 用python生成一个导出数据库的bat脚本文件
  5. WebConfig节点详解
  6. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
  7. 洛谷P1156 垃圾陷阱
  8. ci实现RBAC,详细解释原理和核心代码显示
  9. STM32的SPI问题。
  10. 高并发网络编程之epoll详解
  11. C++通过域名获取IP地址的方法;调试通过!
  12. [Bootstrap] 8. 'Collapse', data-target, data-toggle & data-parent
  13. HDU 5936 Difference 【中途相遇法】(2016年中国大学生程序设计竞赛(杭州))
  14. 31.Spring-开发流程.md
  15. java中post和get请求
  16. 用Left join代替not in
  17. Win7 安装bundle
  18. boost.python入门教程 ----python 嵌入c++
  19. Asterisk 11 chan_sip.c: Failed to authenticate device 看不到IP的问题
  20. windows上使用metastore client java api链接hive metastore问题

热门文章

  1. b9934107349625014ec251e1333d73a8 这个代码是mad5值
  2. bzoj:1575: [Usaco2009 Jan]气象牛Baric
  3. GDKOI2016 游记
  4. [bzoj3953] [WF2013]Self-Assembly
  5. Gym100971B Gym100971C Gym100971F Gym100971G Gym100971K Gym100971L(都是好写的题。。。) IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13, 2016
  6. BZOJ 3106: [cqoi2013]棋盘游戏(对抗搜索)
  7. Bellman-Ford 求含负权最短路
  8. 01-01_环境准备_pyenv
  9. 教你上传本地代码到github转载
  10. [国嵌笔记][030][U-Boot工作流程分析]