Socket接口
Socket接口
Socket: Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。
1.简单的套接字通信
服务端
import socket #1.买手机 创建一个套接字对象
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #基于网络通信的套接字 (TCP)
# print(phone) #2.绑定手机卡(ip地址)
phone.bind(('127.0.0.1',8080)) # 端口0-65535: 0-1024是给操作系统使用的 #3.开机
phone.listen(5) #最大挂起的链接数 #4.等电话链接
print('starting...')
conn,client_addr=phone.accept() #conn 电话线 拿到可以收发信息的管道
#accept 对应客户端的connect 三次握手 #5.收,发消息
data = conn.recv(1024) #1.单位:bytes 2. 1024代表接受1024个bytes
print('客户端的数据',data) conn.send(data.upper()) #6.挂电话
conn.close() #7.关机
phone.close()
客户端
import socket #1.买手机 客户端的phone 相当于服务端的conn
phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
# print(phone) #2.拨号 (服务端的ip 和服务端的 端口)
phone.connect(('127.0.0.1',8080)) #0-65535: 0-1024是给操作系统使用的 #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',8081))
phone.listen(5) print('starting...')
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(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8081)) #0-65535: 0-1024是给操作系统使用的 while True:
msg = input('>>: ').strip()
phone.send(msg.encode('utf-8'))
data = phone.recv(1024)
print(data)
phone.close()
3.C与S的bug修复

BUG问题:
1.端口的重复使用
问题:重启服务端时可能会遇到

这个是由于你的服务端仍然存在四次挥手的time_wait状态在占用地址
windows解决方法
#服务端代码
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip端口重用
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 时间
2.客户端关闭
服务端
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip 端口重用
phone.bind(('127.0.0.1',8080))
phone.listen(5) print('starting...')
conn,client_addr=phone.accept()
print(client_addr) while True: #通信循环
try:
data = conn.recv(1024)
# if not data:break #适用于linux操作系统
print('客户端的数据',data)
conn.send(data.upper())
except ConnectionResetError:#使用于windows操作系统
break conn.close()
phone.close(
客户端
客户端应用程序在发送的时候:send==空-->客户端的操作系统内存 收到为空---> 不会调用任何协议,没有发送数据给,服务端的操作系统内存
服务端应用程序在接受的时候:服务端的操作系统内存由于没有接收到数据,所以一直卡在,应用程序的recv接受过程
import socket phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) #0-65535: 0-1024是给操作系统使用的 while True:
msg = input('>>: ').strip() # msg =''
if not msg:continue
phone.send(msg.encode('utf-8')) #phone.send(b'')
# print('has send') #验证可以发空
# >>: has send
data = phone.recv(1024)
# print('has recv') #验证在发空的情况下 是否可以接受消息
#>>: has send
print(data.decode('utf-8')) phone.close()
4.加上链接通信
服务端一直对外进行服务:可以保证客户端一个一个链接进来
链接新的客户端的条件:停止前一个客户端
服务端
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip 端口重用
phone.bind(('127.0.0.1',8080))
phone.listen(5) print('starting...')
while True: # 链接循环
conn,client_addr=phone.accept()
print(client_addr) while True: #通信循环
try:
data = conn.recv(1024)
# if not data:break #适用于linux操作系统
print('客户端的数据',data)
conn.send(data.upper())
except ConnectionResetError:#使用于windows操作系统
break
conn.close() phone.close()
客户端
import socket phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) #0-65535: 0-1024是给操作系统使用的 while True:
msg = input('>>: ').strip() # msg =''
if not msg:continue
phone.send(msg.encode('utf-8')) #phone.send(b'')
# print('has send') #验证可以发空
# >>: has send
data = phone.recv(1024)
# print('has recv') #验证在发空的情况下 是否可以接受消息
#>>: has send
print(data.decode('utf-8')) phone.close()
客户端1
import socket phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) #0-65535: 0-1024是给操作系统使用的 while True:
msg = input('>>: ').strip() # msg =''
if not msg:continue
phone.send(msg.encode('utf-8')) #phone.send(b'')
# print('has send') #验证可以发空
# >>: has send
data = phone.recv(1024)
# print('has recv') #验证在发空的情况下 是否可以接受消息
#>>: has send
print(data.decode('utf-8')) phone.close()
5.ssh远程执行命令
windows命令:
- dir: 查看某一文件夹下的子文件名与子文件夹名
- ipconfig: 查看本地网卡的ip信息
- tasklist: 查看运行的进程
linux命令:
- ls
- ifconfig
- pa aux
问题:想要在服务端拿到命令,并且将命令的结果返回给客户端
通过os.system可以执行系统命令,但是只能返回0或者1(命令正确 0 ,命令错误 1),无法返回出系统命令的执行结果
import os
res = os.system('dir E:')
print('命令的结果: ', res)
解决方法:
创建管道:
import subprocess
obj = subprocess.Popen('dirsadas E:',shell=True,
stdout=subprocess.PIPE, #丢到管道里面shell是命令解释器的意思,启动一个程序来解析,前面的字符串,解析成相应的命令
stderr=subprocess.PIPE)
print(obj)
# print('stout 1--->: ',obj.stdout.read().decode('gbk')) #第一次从管道中取走了数据
# print('stout 2--->: ',obj.stdout.read().decode('gbk')) #第二次没有值所以为空 print('stderr 1--->: ',obj.stderr.read().decode('gbk')) # 拿到错误管道的数据 #在解码的时候,必须考虑到编码的格式,在管道里执行系统命令的是要提交给系统,
# 所以判断出编码的格式是 windows默认的编码gbk
服务端
import socket
import subprocess phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #SO_REUSEADDR 可以让ip 端口重用
phone.bind(('127.0.0.1',8080))
phone.listen(5) print('starting...')
while True: # 链接循环
conn,client_addr=phone.accept() #接受客户端链接
print(client_addr) while True: #通信循环
try:
#1.收命令
data = conn.recv(1024)
print('客户端的数据',data) #2.执行命令,拿到结果
obj = subprocess.Popen(data.decode('utf-8'), shell=True,
stdout=subprocess.PIPE, # 丢到管道里面
stderr=subprocess.PIPE) # shell是命令解释器的意思,启动一个程序来解析,前面的字符串,解析成相应的命令 stdout = obj.stdout.read()
stderr = obj.stderr.read() #3.把命令的结果返回给客户端
conn.send(stdout+stderr) # '+'是可以优化的点 except ConnectionResetError:# 使用于windows操作系统
break
conn.close() phone.close()
客户端
import socket
phone=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080))
while True:
#1.发命令
cmd = input('>>: ').strip() #dir C:
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#2.拿命令的结果,并打印
data = phone.recv(1024) # 1024是一个坑
print(data.decode('gbk')) #系统默认的编码
phone.close()
Socket接口的更多相关文章
- Java语言Socket接口用法详解
Socket接口用法详解 在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...
- 【1】HTTP协议和Socket接口区别
内容提要: 1.网络七层模型 2.什么是HTTP协议 3.什么是Socket接口 1.网络七层模型 第一层:物理层 为设备之间的信息提供传输提供可靠环境,那么这个环境是什么呢? 如:同轴电缆,插头,接 ...
- socket接口详解
1. socket概述 socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信. socket起源于UNIX,在Unix一切 ...
- Socket接口原理及用C#语言实现
首先从原理上解释一下采用Socket接口的网络通讯,这里以最常用的C/S模式作为范例,首先,服务端有一个进程(或多个进程)在指定的端口等待客户来连接,服务程序等待客户的连接信息,一旦连接上之后,就可以 ...
- linux网络socket 接口转
linux网络socket 接口 1.socket函数:一个进程必须做的第一件事就是调用socket函数获得一个文件描述符. ------------------------------------- ...
- Windows Socket 接口简介
Windows Socket接口是Windows下网络编程的接口,在介绍Windows Socket接口之前,首先要简单介绍一下TCP/IP协议和描述网络系统架构的 OSI模型,以及TCP/IP模型 ...
- JMETER之socket接口性能测试
公司的**产品经过换代升级,终于要上线了,纯java编码,包括POS(PC/安卓平板)版.WEB版.微信版,各终端通过 Webservice服务共享数据资源,因此Webservice各接口的性能测试就 ...
- unix socket接口
socket 创建套接字文件: #include <sys/socket.h> // 成功返回非负套接字描述符,失败返回-1 int socket(int domain, int type ...
- LoadRunner 测试Socket接口函数说明
lrs_save_param_ex是lrs_save_param的扩展函数,包含了lrs_save_param的基本功能.其函数语法结构如下: int lrs_save_param_ex ( char ...
随机推荐
- 设计模式-创建型模式,python享元模式 、python单例模式(7)
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...
- MTK 自定义按键添加广播
一.给自定义按键添加广播 修改PhoneWindowManager.java中的interceptKeyBeforeDispatching方法 /frameworks/base/policy/src/ ...
- PHP实现删除非站内外部链接实例代码
/** * 删除非站内链接 * * @access public * @param string $body 内容 * @param array $allow_urls ...
- 13组合模式Composite
一.什么是组合模式 Composite模式也叫组合模式,是构造型的设 计模式之一.通过递归手段来构造树形的对象结 构,并可以通过一个对象来访问整个对象树. 二.组合模式的结构 三.组合模式的角色和职责 ...
- spring框架学习感悟
学习了一段时间的spring,但是在练习时老是出现bug,一方面,框架封装了很多东西,简化了开发,但是万一出现问题,就很难排查.这说明应该找个慢慢的熟悉它,并且掌握它. 在这个过程中,可能要不断地试错 ...
- cvLogPolar函数详解
对于二维图形,Log-polar转换表示从笛卡尔坐标到极坐标的变化,广泛应用在计算机视觉中.此函数模仿人类视网膜中央凹视力,并且对于目标跟踪等可用于快速尺度和旋转变换不变模板匹配. 本例程实现极坐标变 ...
- [No000011A]Office Excel设置显示日期与星期
设置excel日期格式,自定义,yyyy-mm-dd 上午/下午 hh:mm:ss AM/PM dddd aaaa
- linux使用rz、sz快速上传、下载文件
平时都使用ftp工具进行文件的上传下载操作,针对于小文件的简单传输来说,有下面好的方法: 首先安装rz.sz工具: #yum install lrzsz 上传文件:rz 下载文件:sz 上传文件在sh ...
- C# Winform同一子窗体只允许打开一次
在winform中一个窗口可以一直打开,是不合理的,解决方法: http://blog.csdn.net/kangkang621/article/details/49664295
- [administrator][netctl] 给未插线未UP端口设置IP
以下内容均为使用netctl配置工具前提下: 需求: Tstation管理口做日常使用.没有千兆交换.所以加一个一块千兆的卡.这块卡是为了做数据传输专用的. 目前主要就是每周给T7备份使用.但是由于是 ...