网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令
1.简单的套接字通信 服务端
'''
服务端 接电话
客户端 打电话
1.先启动服务端
2.服务端有两种套接字
1.phone 用来干接收链接的
2.conn 用来干收发消息的 '''
import socket
# 1.买手机
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 基于网络通信的 基于tcp通信的套接字
# print(phone)
# <socket.socket fd=416, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0> # 2.绑定手机卡(IP地址) 运行这个软件的电脑IP地址 ip和端口都应该写到配置文件中
phone.bind(('127.0.0.1',8080)) # 端口0-65535 0-1024 给操纵系统 # 3.开机
phone.listen(5) # 5 代表最大挂起的链接数 # 4.等电话链接
print('starting...')
# res = phone.accept() #底层 就是 tcp 三次握手
# print(res)
# (<socket.socket fd=476, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 58886)>, ('127.0.0.1', 58886))
conn,client_addr = phone.accept() # conn 电话线 拿到可以收发消息的管道 conn对象 # 5.收发消息
data = conn.recv(1024) # 1024个字节 1.单位:bytes 2.1024代表最大接收1024个bytes
print(data) conn.send(data.upper()) # 6.挂电话
conn.close() # 7.关机
phone.close()
客户端
'''
服务端 接电话
客户端 打电话
1.客户端有一种套接字:
phone 用来建连接请求 并用来收发消息
'''
import socket
# 1.买手机 客户端的phone 相当于服务端的 conn
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 基于网络通信的 基于tcp通信的套接字
# print(phone) # 2.拨号 (服务端的ip 和服务端的 端口)
phone.connect(('127.0.0.1',8080)) #phone 拿到可以发收消息的管道 phone 对象 # 3.发收消息 bytes型
phone.send('hello'.encode('utf-8'))
data = phone.recv(1024)
print(data) # 4.关闭
phone.close()
2.加上通信循环 服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('strating...')
conn,client_addr = phone.accept()
print(client_addr)
while True: # 通信循环
data = conn.recv(1024)
print('客户端数据:',data)
conn.send(data.upper()) conn.close()
phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True: # 通信循环
msg = input('msg>>>:').strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data) phone.close()
3.bug修复
端口已存在 重用一下:
http://www.cnblogs.com/linhaifeng/articles/6129246.html
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
还有一种 linux 操作系统 修改内核参数 让os 尽可能快的回收端口
有时os回收端口慢 客户端断开: linux 解决办法:if not data:break
wwindows 解决办法:try...except
问题:

这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址 windows解决办法:
#加入一条socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080)) linux 解决办法:
发现系统存在大量TIME_WAIT状态的连接,通过调整linux内核参数解决,
vi /etc/sysctl.conf 编辑文件,加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30 然后执行 /sbin/sysctl -p 让参数生效。 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系統默认的 TIMEOUT 时间
服务端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8080)) #如果端口已被占用 就换一个
phone.listen(5)
print('strating...')
conn,client_addr = phone.accept() # conn 三次握手的成果 双向链接
print(client_addr)
while True: # 通信循环
try: # try...except 出异常适合windows 出异常这里指客户端断开
data = conn.recv(1024) # 如何客户端 断开了 linux 就会死循环
# if not data:break # 出异常才会有 # 这里适合linux 出异常指客户端断开
print('客户端数据:',data)
conn.send(data.upper())
except ConnectionResetError: # 适用windows os
break conn.close()
phone.close()
客户端
send 可以发 空 # 发给了os的内存 在调用网卡 发送数据
recv 不可以 收空 # 到了os的内存 在传给了应用程序内存
所以 客户端 就卡住了 if not msg:continue 卡住原因 os 不会发''数据
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('127.0.0.1',8080))
while True: # 通信循环
msg = input('msg>>>:').strip() # ''
if not msg:continue
# 这个调用了硬件 应用程序里的内存传给了os的内存,由os 调用网卡传数据
phone.send(msg.encode('utf-8')) # b''
# print('has send') # 打印了 证明可以 发 空 ''
# 和os要数据,你帮我调用网卡 收数据
data = phone.recv(1024)
# print('has recv')
# print(data)
print(data.decode('utf-8')) #解码 phone.close()
4.加上链接循环 服务端
'''
服务端:不断的接收客户端的 连接
服务端accept 这里不是并发 的效果 但可以一个一个接收客户端的连接
phone.listen(5) 监听5个
'''
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',8080))
phone.listen(0)
print('strating...')
while True: #连接循环 没有并发 但可一个一个 接收客户端 干通信活的同时不能干连接
conn,client_addr = phone.accept() # 现在没并发 只能一个一个
print(client_addr) while True:
try:
data = conn.recv(1024)
if not data:break
print('客户端数据:',data)
conn.send(data.upper())
except ConnectionResetError:
break
conn.close() phone.close()
客户端1
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
msg = input('msg>>>:').strip() # ''
if not msg:continue
phone.send(msg.encode('utf-8')) # b''
data = phone.recv(1024)
print(data.decode('utf-8')) #解码 phone.close()
客户端2
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
msg = input('msg>>>:').strip() # ''
if not msg:continue
phone.send(msg.encode('utf-8')) # b''
data = phone.recv(1024)
print(data.decode('utf-8')) #解码 phone.close()
5.模拟ssh远程执行命令
什么叫命令?
windows:
dir:查看某一个文件夹下的子文件名与子文件夹名
ipconfig:查看本地网卡的ip信息
tasklist:查看运行的进程
Linux:
ls
ifconfig
ps aux 如何执行系统命令: 并拿到执行结果
import os
os.system # 只能拿到 运行结果 0 执行成功 非0 失败
一般用:
import subprocess
subprocess.Popen('dir d:',shell=True) # shell 启了一个cmd
把命令结果丢到管道里面:
subprocess.Popen('dir d:',shell=True,
stdout=subprocess.PIPE)
# import os
# res = os.system('dir d:')
# print(os.system('dir d:'))
# # print(res) import subprocess
obj=subprocess.Popen('dir d:ss',shell=True,
stdout=subprocess.PIPE, # 正确的结果
stderr=subprocess.PIPE) # 错误的结果
print(obj) # 执行的结果 是bytes
print('stdout 1--:',obj.stdout.read().decode('gbk')) # linux 是 utf-8 windows 是 gbk
print('stdout 2--:',obj.stdout.read().decode('gbk')) # 因为管道没有了
print('stdout 3--:',obj.stderr.read().decode('gbk')) # 错误管道里有 原因 拿不到数据
服务端
import subprocess
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 重用ip和端口 任然存在4次挥手的状态 解决办法
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('strating...')
while True:
conn,client_addr = phone.accept()
print(client_addr) while True:
try:
# 1.收命令
cmd = conn.recv(1024)
if not cmd:break
print('客户端数据:',cmd) # 2.执行命令,拿到结果
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True, # 客户端用 utf-8发的
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read() # 3.把命令的结果返回给客户端
print(len(stdout)+len(stderr))
conn.send(stdout+stderr) # 有效率问题的 这里 之后 可以优化
except ConnectionResetError:
break
conn.close() phone.close()
客户端
import socket
phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
# 1.发命令
cmd = input('msg>>>:').strip() # dir ls
if not cmd:continue
phone.send(cmd.encode('utf-8')) # 2.拿到命令的结果,并打印
data = phone.recv(1024) # 这里是个坑 有可能会大于1024 接收数据量的最大限制
# data = phone.recv(526) # 这里是个坑 有可能会大于1024 接收数据量的最大限制 print(data.decode('gbk')) # linux:utf-8 windows:gbk phone.close()
网络编程 - 1.简单的套接字通信/2.加上通信循环/3.bug修复/4.加上链接循环/5.模拟ssh远程执行命令的更多相关文章
- 网络编程之模拟ssh远程执行命令、粘包问题 、解决粘包问题
目录 模拟ssh远程执行命令 服务端 客户端 粘包问题 什么是粘包 TCP发送数据的四种情况 粘包的两种情况 解决粘包问题 struct模块 解决粘包问题 服务端 客户端 模拟ssh远程执行命令 服务 ...
- 网络编程基础之Socket套接字简单应用
一.Socket套接字实现通信循环 所谓通信循环,简单理解就是客户端可以给服务端循环发送信息并获得反馈的过程. 1.基础版 通信循环的程序分为两部分,即两个python模块,分别为客户端.py和服务端 ...
- [转载] 读《UNIX网络编程 卷1:套接字联网API》
原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...
- 网络编程初识和socket套接字
网络的产生 不同机器上的程序要通信,才产生了网络:凡是涉及到倆个程序之间通讯的都需要用到网络 软件开发架构 软件开发架构的类型:应用类.web类 应用类:qq.微信.网盘.优酷这一类是属于需要安装的桌 ...
- 网络编程基础之Socket套接字
一.Socket介绍 1.什么是socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族 ...
- 网络编程(socket,套接字)
服务端地址不变 ip + mac 标识唯一一台机器 ip +端口 标识唯一客户端应用程序 套接字: 网络编程 网络编程 一.python提供了两个级别访问的网络服务 低级别的网络服务支持基本的 S ...
- 《Unix网络编程卷1:套接字联网API》读书笔记
第一部分:简介和TCP/IP 第1章:简介 第2章:传输层:TCP.UDP和SCTP TCP:传输控制协议,复杂.可靠.面向连接协议 UDP:用户数据报协议,简单.不可靠.无连接协议 SCTP:流控制 ...
- 【TCP/IP网络编程】:09套接字的多种可选项
本篇文章主要介绍了套接字的几个常用配置选项,包括SO_SNDBUF & SO_RCVBUF.SO_REUSEADDR及TCP_NODELAY等. 套接字可选项和I/O缓冲大小 前文关于套接字的 ...
- 《UNIX网络编程 卷1:套接字联网API》读书笔记(一):网络编程简介
概述 要编写通过计算机网络通信的程序,首先要确定这些程序相互通信所用的协议.大多数网络是按照划分成客户和服务器来组织的.本章及后续章节的焦点是TCP/IP协议族,也可称为网际协议族.下图为客户与服务器 ...
随机推荐
- 《LAMP系统工程师实用教程》读书笔记(一)- linux常用命令
图书馆看到就借回来啦,这本书虽然其貌不扬,对新手还是挺棒的.来学下shell脚本和php. 把书上不熟悉的命令和选项记录下. mkdir -v创建文件夹并返回信息 mkdir -m创建文件夹并设定权限 ...
- 深入剖析 linux GCC 4.4 的 STL string
转自: 深入剖析 linux GCC 4.4 的 STL string 本文通过研究STL源码来剖析C++中标准模板块库std::string运行机理,重点研究了其中的引用计数和Copy-On-Wri ...
- Django REST framework 知识点总结
一.安装DjangoREST framework #先安装Django #安装必要的包 pip install djangorestframework coreapi (1.32.0+) - Sche ...
- vs2015开发so动态库linux
#include <stdio.h> #include <dlfcn.h> typedef int(*fn_max)(int a, int b); int main() { p ...
- PHP的数据类型转换
PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: •(int).(integer):转换成整形 •(float).(double).(real):转换成浮点型 •(string):转换成 ...
- Lucene 工作原理<转>
Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构.该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I l ...
- awk 计算数据的和和平均值
awk 计算数据的和和平均值 2014年12月02日 21:11:12 HaveFunInLinux 阅读数:14487更多 个人分类: 小技巧 本文译至:http://d.hatena.ne.j ...
- 浅谈Unity中的GC以及优化
介绍: 在游戏运行的时候,数据主要存储在内存中,当游戏的数据不在需要的时候,存储当前数据的内存就可以被回收再次使用.内存垃圾是指当前废弃数据所占用的内存,垃圾回收(GC)是指将废弃的内存重新回收再次使 ...
- 利用QtGraphicalEffects来使得自己的图像显示更加生动
有兴趣的开发人员能够參阅连接http://doc.qt.io/qt-5/qtgraphicaleffects-qmlmodule.html来深度学习Qt对Graphics方面的处理. 在今天的这篇文章 ...
- C# 压缩和解压文件(SharpZipLib)
先从网上下载ICSharpCode.SharpZipLib.dll类库 将文件或文件夹压缩为zip,函数如下 /// <summary> /// 压缩文件 /// </summary ...