前言

  基于网络通信(AF_INET)的socket(套接字)实现了TCP/UDP协议

目录


基于TCP协议的socket

服务端

#服务端
from socket import * #AF_INIT(基于网络通信) SOCK_STREAM(TCP协议)(买手机)
tcp_server= socket(AF_INET,SOCK_STREAM) #防止端口FIN_WAIT状态,重用ip和端口(4次挥手断开连接需要时间)
#tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #绑定ip和端口(插手机卡)
tcp_server.bind(('127.0.0.1',8080)) #可以挂起几个连接(开机)
tcp_server.listen(5) while True:
#服务端等待连接(等电话)
conn, addr = tcp_server.accept() while True: #通话中
try:
# 接收buffer_size个字节的信息 (收消息)
data = conn.recv(1024)
# (发消息)
conn.send(data.upper())
except Exception as e: #客户端错误方式关闭连接,退出
print(e,'客户端断开连接')
break # 关闭连接 (挂电话)
conn.close() # 关闭服务 (关机)
tcp_server.close()

客户端

#客户端
from socket import * #开机
tcp_client= socket(AF_INET,SOCK_STREAM)
#拨通电话
tcp_client.connect(('127.0.0.1',8080)) while True:
msg = input('>>:').strip()
#发消息
tcp_client.send(msg.encode('utf-8'))
#收消息
data = tcp_client.recv(1024)
print(data.decode('utf-8')) #关机
tcp_client.close()
#服务端
from socket import * ip_port = ('127.0.0.1',8080)
back_log = 5
buffer_size = 1024 tcp_server= socket(AF_INET,SOCK_STREAM) #AF_INIT(基于网络通信) SOCK_STREAM(TCP协议)(买手机)
tcp_server.bind(ip_port) #绑定ip和端口(插手机卡)
tcp_server.listen(back_log) #可以挂起几个连接(开机)
while True:
conn, addr = tcp_server.accept() # 服务端等待连接(等电话)
print('双向链接', conn)
print('客户端地址', addr) while True:
try:
data = conn.recv(buffer_size) # 接收buffer_size个字节的信息 (收消息)
print("客户端发来的消息", data.decode('utf-8'))
conn.send(data.upper()) # (发消息)
except Exception:
break conn.close() #关闭连接 (挂电话)
tcp_server.close() #关闭服务 (关机) '''
输出:
双向链接 <socket.socket fd=516, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 47586)>
客户端地址 ('127.0.0.1', 47586)
客户端发来的消息 chen
'''

服务端

#客户端
from socket import * ip_port = ('127.0.0.1',8080)
back_log = 5
buffer_size = 1024 tcp_client= socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port) #拨通电话
while True:
msg = input('>>:').strip()
tcp_client.send(msg.encode('utf-8')) #发消息
print('客户端已经发送消息')
data = tcp_client.recv(buffer_size) #收消息
print('收到服务端发送的消息',data.decode('utf-8')) tcp_client.close() #关机 '''
输出:
>>:chen
客户端已经发送消息
收到服务端发送的消息 CHEN
'''

客户端

基于UDP协议的socket

服务端  

#服务端
from socket import * #AF_INIT(基于网络通信) SOCK_DGRAM(数据报式)
udp_server= socket(AF_INET,SOCK_DGRAM) #防止端口FIN_WAIT状态,重用ip和端口(4次挥手断开连接需要时间)
#udp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #绑定ip和端口(插手机卡)
udp_server.bind(('127.0.0.1',8080)) while True:
#接收消息
data,addr = udp_server.recvfrom(1024) #按客户端ip和端口发送
udp_server.sendto(data.upper(),addr) udp_server.close()  

客户端

#客户端
from socket import * #开机
udp_client= socket(AF_INET,SOCK_DGRAM) while True:
msg = input('>>:').strip() #向指定ip和端口发消息
udp_client.sendto(msg.encode('utf-8'),('127.0.0.1',8080))
#收消息,返回数据和服务器ip
data,addr = udp_client.recvfrom(1024) udp_client.close()

TCP协议下粘包现象及处理  

tcp协议下会产生粘包现象,即当前的命令结果与上一条的命令结果粘在了一起。

产生粘包现象的原因有两个:

  1.  tcp是面向流的协议, tcp_client.recv() 设置的一次接收的size小于服务器传输过来的字节大小,当客户端从缓存的拿去接收的数据时,没有全部取走,而缓存中是以队列的形式存储,当再一次执行命令的时候会收到上一次命令结果的后半部分与当前命令结果连接在一起的结果   

  2.  tcp下使用Nagle算法优化,会将间隔较小且数据较小的数据,合成一个较大的数据块一起发送

解决方法:粘包现象的根本是,不知道发送数据的大小 

from socket import *
import subprocess
import struct
ip_port=('127.0.0.1',8080)
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) #执行命令,得到命令的运行结果cmd_res
res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
stdin=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)
conn.send(data_length)
conn.send(cmd_res) except Exception as e:
print(e)
break

远程登录服务端

from socket import *
import struct
from functools import partial
ip_port=('127.0.0.1',8080)
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) print('命令的执行结果是 ',recv_msg.decode('gbk')) tcp_client.close()

远程登录客户端

使用socketserver模块实现高并发

tcp服务端  

class MyServer(socketserver.BaseRequestHandler):

    #通信循环在在内部会调用handlle方法
def handle(self): #在打电话中
print('conn is: ',self.request) #conn
print('addr is: ',self.client_address) #addr while True:
try:
  #收消息
data=self.request.recv(1024)
if not data:break
print('收到客户端的消息是',data,self.client_address) #发消息
self.request.sendall(data.upper()) except Exception as e:
print(e)
break if __name__ == '__main__':
s=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyServer) #多线程
s.serve_forever()

udp服务端

import socketserver

class MyServer(socketserver.BaseRequestHandler):
def handle(self):
print(self.request)
print('收到客户端的消息是',self.request[0])
self.request[1].sendto(self.request[0].upper(),self.client_address) if __name__ == '__main__':
s=socketserver.ThreadingUDPServer(('127.0.0.1',8080),MyServer)
s.serve_forever()

  

python之路(12)网络编程的更多相关文章

  1. Python之路,Day8 - Socket编程进阶

    Python之路,Day8 - Socket编程进阶   本节内容: Socket语法及相关 SocketServer实现多并发 Socket语法及相关 socket概念 socket本质上就是在2台 ...

  2. python下的复杂网络编程包networkx的安装及使用

    由于py3.x与工具包的兼容问题,这里采用py2.7 1.python下的复杂网络编程包networkx的使用: http://blog.sina.com.cn/s/blog_720448d30101 ...

  3. python六十七课——网络编程(基础知识了解)

    网络编程: 什么是网络编程? 网络:它是一种隐形的媒介:可以将多台计算机使用(将它们连接到一起) 网络编程:将多台计算机之间可以相互通信了(做数据交互) 一旦涉及到网络编程,划分为两个方向存在,一方我 ...

  4. Python之路【第七篇】python基础 之socket网络编程

    本篇文章大部分借鉴 http://www.cnblogs.com/nulige/p/6235531.html python socket  网络编程 一.服务端和客户端 BS架构 (腾讯通软件:ser ...

  5. python的学习之路day7-socket网络编程

    python基础部分学习完了,时间也已经过了两个月左右,感觉没学到什么,可能是我学习之后忘记的太多了. 由于没钱买书,要是去培训就更没钱了,所以在网上找了一本书,感觉还不错,讲的比较好,比较详细. P ...

  6. Python进阶开发之网络编程,socket实现在线聊天机器人

    系列文章 √第一章 元类编程,已完成 ; √第二章 网络编程,已完成 ; 本文目录 什么是socket?创建socket客户端创建socket服务端socket工作流程图解socket公共函数汇总实战 ...

  7. python之旅:网络编程

    一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频 ...

  8. Python基础-week07 Socket网络编程

    一 客户端/服务器架构 1.定义 又称为C/S架构,S 指的是Server(服务端软件),C指的是Client(客户端软件) 本章的中点就是教大写写一个c/s架构的软件,实现服务端软件和客户端软件基于 ...

  9. python(38)- 网络编程socket

    一 客户端/服务器架构 即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 美好的愿望: 最常用的软件服务器是 Web 服务器.一台机器里放一些网页或 Web 应用程序 ...

  10. python学习笔记11 ----网络编程

    网络编程 网络编程需要知道的概念 网络体系结构就是使用这些用不同媒介连接起来的不同设备和网络系统在不同的应用环境下实现互操作性,并满足各种业务需求的一种粘合剂.网络体系结构解决互质性问题彩是分层方法. ...

随机推荐

  1. 用 Python 描述 Cookie 和 Session

    这篇文章我们来聊聊Cookie和Session,网上有很多关于这两个知识点的描述,可惜的是大部分都没有示例代码,因此本文的重点在于示例代码. 环境 Python3.6.0 Bottle0.12.15 ...

  2. RAID5当一块硬盘离线后处理

    RAID5当一块硬盘离线后,处理降级状态,这时候正常的建议是马上更换硬盘做REBUILD以恢复完整的数据状态,如果有热备盘的话,就会自动做REBUILD,这样做合适吗? 一组RAID卷在工作很长时间以 ...

  3. Exchange 2010邮件服务器的搭建和部署

    Exchange主要是针对内部网或者企业网用户进行搭建的邮件服务器软件,利用它能够很快地搭建安全性较高的内部网邮件系统. 本次搭建在个人环境中实践,纯属爱好折腾,分四步骤,1.搭建windows 20 ...

  4. 我的第一个python web开发框架(36)——后台菜单管理功能

    对于后台管理系统来说,要做好权限管理离不开菜单项和页面按钮控件功能的管理.由于程序没法智能的知道有什么菜单和控件,哪些人拥有哪些操作权限,所以首先要做的是菜单管理功能,将需要管理的菜单项和各个功能项添 ...

  5. 【spring源码分析】IOC容器初始化(十)

    前言:前文[spring源码分析]IOC容器初始化(九)中分析了AbstractAutowireCapableBeanFactory#createBeanInstance方法中通过工厂方法创建bean ...

  6. 使用git 遇见的错误使用到的命令

    查看远端地址  git remote -v 需要重新添加地址  git remote set-url origin xxx 远程新的地址 git remote add origin_new 设置用户名 ...

  7. 机器翻译评价指标 — BLEU算法

    1,概述 机器翻译中常用的自动评价指标是 $BLEU$ 算法,除了在机器翻译中的应用,在其他的 $seq2seq$ 任务中也会使用,例如对话系统. 2 $BLEU$算法详解 假定人工给出的译文为$re ...

  8. day20 hashlib、hmac、subprocess、configparser模块

    hashlib模块:加密 import hashlib# 基本使用cipher = hashlib.md5('需要加密的数据的二进制形式'.encode('utf-8'))print(cipher.h ...

  9. cordova 自定义 plugin

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq_30879415/article/details/81265455准备工作安装cordovanp ...

  10. 是时候理解下HTTPS的原理及流程了

    1.什么是HTTP协议? HTTP协议是Hyper Text Transfer Protocol(超文本传输协议),位于TCP/IP模型当中的应用层.HTTP协议通过请求/响应的方式,在客户端和服务端 ...