【python】-- Socket
socket
socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 我们知道网络 通信 都 是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。
一、socket简述
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
socket和file的区别:
- file模块是针对某个指定文件进行【打开】【读写】【关闭】
- socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】
1、客户端小实例:
import socket #导入socket模块 client = socket.socket() #创建socket实例
client.connect(("localhost",6969)) #建立连接
send_data = "hello word!" #发送的字符串
send_data = send_data.encode() #因为发送是bytes类型,所以这边先转码成bytes类型
client.send(send_data) #发送数据
data = client.recv(1024) #接收服务端的数据,这边设置接收1024字节 1kb=1024字节
print("server rece:",data.decode())
client.close() #关闭与服务端的链接
2、服务端小实例:
import socket sever = socket.socket() #创建服务端实例
sever.bind(("localhost",6969)) #绑定客户端ip和端口
sever.listen() #监听端口
print("server waiting connect.........")
conn,addr = sever.accept() #接收客户端,并且返回连接标志位(conn)实例,和对方的ip地址(addr)
data = conn.recv(1024) #接收客户端发过来的数据,接收的也是bytes类型的数据
print("成功建立链接")
print("client data:",data.decode())
conn.send(data.upper()) #将刚刚接收到数据,发送至服务端,注意这边发送的也是字节类型,是bytes类型
sever.close() #关闭服务端
3、socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)参数详解:
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6
socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM 数据报式socket , for UDP
socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET 可靠的连续数据包服务
参数三:协议
0 (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议
Demo:
import socket
ip_port = ('127.0.0.1',9999)
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
sk.bind(ip_port) while True:
data = sk.recv(1024)
print data import socket
ip_port = ('127.0.0.1',9999) sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
while True:
inp = raw_input('数据:').strip()
if inp == 'exit':
break
sk.sendto(inp,ip_port) sk.close()
二、Socket方法、简单ssh实例
1、socket方法:
函数 | 描述 |
---|---|
服务器端套接字 | |
s.bind() | 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。 |
s.listen() | 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 |
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字 | |
s.connect() | 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。 |
s.connect_ex() | connect()函数的扩展版本,出错时返回出错码,而不是抛出异常 |
公共用途的套接字函数 | |
s.recv() | 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。 |
s.send() | 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 |
s.sendall() | 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 |
s.recvform() | 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 |
s.sendto() | 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 |
s.close() | 关闭套接字 |
s.getpeername() | 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。 |
s.getsockname() | 返回套接字自己的地址。通常是一个元组(ipaddr,port) |
s.setsockopt(level,optname,value) | 设置给定套接字选项的值。 |
s.getsockopt(level,optname[.buflen]) | 返回套接字选项的值。 |
s.settimeout(timeout) | 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect()) |
s.gettimeout() | 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。 |
s.fileno() | 返回套接字的文件描述符。 |
s.setblocking(flag) | 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。 |
s.makefile() | 创建一个与该套接字相关连的文件 |
2、简单ssh实例:
客户端:
客户端实例->建立连接->发送数据->接收数据
import socket client = socket.socket()
client.connect(("localhost",9999)) while True:
cmd = input(">>>:").strip()
if len(cmd) == 0:continue
client.send(cmd.encode("utf-8"))
cmd_res = client.recv(500)
print(cmd_res.decode("utf-8",'ignore')) client.close()
服务端:
服务端实例->绑定ip+端口->监听客户端连接->生成连接实例->接收客户端数据->发送数据至客户端
import socket,os server = socket.socket()
server.bind(("localhost",9999))
server.listen()
while True:
conn,addr = server.accept()
print("new addr:",addr)
while True:
data = conn.recv(1024)
if not data:
print("客户端已断开")
break
print("执行指令:",data)
cmd_res = os.popen(data.decode()).read()
print("before send:",len(cmd_res))
if len(cmd_res) == 0:
cmd_res = "cmd has no output...."
conn.send(cmd_res.encode("utf-8"))
print("send done")
server.close()
效果图:
Pycharm 执行命令:ipconfig
cmd执行命令:ipconfig
通过效果图对比发现Pycharm执行的ipconfig信息显示不完成,原因就是我们在客户端的代码 cmd_res = client.recv(500) 设置接受的字节最大就是500,服务端的发送给客户端的信息大于500 字节,多出的字节就会被存放在IO缓冲区,等待下一次发送。
流程图
ssh 实例小结:
1、服务端第一次全部发送给客户端,客户端只接收设置部分的字节数,剩下的字节数被存储在 IO缓冲区 中,下一次再用send的时候,它会先把缓冲区里的旧数据先发出去,等达到客户端接收的最大值后,然后再把新数据再放到缓冲区中,直到缓冲区满了再发出去
2、客户端虽然写的接收的是500,但它不一定能收到500,recv(500)代表着最多一次只能收500,如果服务端send10个字节,客户端也会正常接收,而不是等着500全收满了
3、两种情况缓冲区会发数据:
- 缓冲区满了会发
- 缓冲区超时:就是手动send
【python】-- Socket的更多相关文章
- 【Python】socket模块应用
[Socket] 本文记录了一些socket模块的简单应用,对于具体原理还没来得及深究. ■ 利用socket模块进行端口连接验证和扫描 在linux中常用nc命令来进行远端端口是否开放的验证.但是这 ...
- 【python】-- Socket接收大数据
Socket接收大数据 上一篇博客中的简单ssh实例,就是说当服务器发送至客户端的数据,大于客户端设置的数据,则就会把数据服务端发过来的数据剩余数据存在IO缓冲区中,这样就会造成我们想要获取数据的完整 ...
- 【Python】socket编程-3
. SocketServer最简单的使用方法: () 创建一个Handler类,继承自BaseRequestHandler,重写其handle(),在该方法中完成对请求的处理. () 实例化一个Ser ...
- 【Python】socket编程-2
#练习3:TCP协议+while循环 服务端: import socket #socket模块 import sys reload(sys) sys.setdefaultencoding(" ...
- 【Python】socket编程-1
一.什么是socket编程:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,编程传输层,socket本质是编程接口(API) 二.网络七层协议:物里层 数据链 ...
- 【python】socket
UDP udp_server.py from datetime import datetime import socket server_address = ('localhost', 6789) m ...
- 【python】-- Socket粘包问题 ,解决粘包的几种方法、socket文件下载,md5值检验
上一篇随笔:“socket 接收大数据”,在win系统上能够运行,并且解决了大数据量的数据传输出现的问题,但是运行在linux系统上就会出现如下图所示的情况: 就是服务端两次发送给客户端的数据(第一次 ...
- 【Python】【网络编程】
#[[网络编程]] # 网络通信就是两个进程之间在通信 # [TCP/IP]'''TCP/IP简介 阅读: 125242虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联 ...
- 【python】列出http://www.cnblogs.com/xiandedanteng中所有博文的标题
代码: # 列出http://www.cnblogs.com/xiandedanteng中所有博文的标题 from bs4 import BeautifulSoup import requests u ...
随机推荐
- Linux内核性能测试工具全景图
1.Linux性能监控工具及对应的内核层 2.Linux性能基础测试工具及对应内核层 3.Linux性能监控工具Sar及对应内核层 4.Linux性能调优工具及对应的内核层
- Exposing the Outlook Password Secrets
Exposing the Outlook Password Secrets - www.SecurityXploded.comhttp://securityxploded.com/outlookpas ...
- AnimatorStateInfo
AnimatorStateInfo Namespace: UnityEngine Description Information about the current or next state. ...
- python——iterator迭代器|iterator详解——20140918|
-----------------------------------------------------------------------------前言--------------------- ...
- react-native 项目实战 -- 新闻客户端(6) -- 完善ListView头部视图
1.因为需要定时器,所以我们要cd到当前项目根目录下安装这个类库: $ npm i react-timer-mixin --save 2.Component/ScrollImage.js /** * ...
- mui 本地打包
第一步:下载HBuilder离线打包Android版SDK 网址:http://ask.dcloud.net.cn/article/38 第二步:导入项目 启动带ADT的eclipse程序,菜单中选择 ...
- Mybatis 批量插入数据
--mybatis 批量插入数据 --1.Oracle(需要测试下是否支持MySQL) < insert id ="insertBatch" parameterType=&q ...
- 键盘上所有键位的ascii值
上次用的时候一直找,这次找到了,收藏起来. 0x1 鼠标左键 0x2 鼠标右键 0x3 CANCEL 键 0x4 鼠标中键 0x8 BACKSPACE 键 0x9 TAB 键 0xC CLEAR 键 ...
- Android网络框架Volley
Volley是Google I/O 2013推出的网络通信库,在volley推出之前我们一般会选择比较成熟的第三方网络通信库,如: android-async-http retrofit okhttp ...
- 2d-Lidar 点云多直线拟合算法
具体步骤: EM+GMM(高斯模糊模型) 点云分割聚类算法的实现. 基于RANSAC单帧lidar数据直线拟合算法实现. 多帧lidar数据实时直线优化算法实现. 算法实现逻辑: Struct lin ...