一、Socket Families 地址簇

  • socket.AF_UNIX
  • socket.AF_INET
  • socket.AF_INET6

    二、Socker Types

  • socket.SOCK_STREAM #tcp
  • socket.SOCK_DGRAM #udp
  • socket.SOCK_RAM
  • socket.SOCK_RDM
  • socket.SOCK_SEQPACKET

    三、socket的收发实例

  • client
# Author:Li Dongfei
import socket
client = socket.socket()  #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))
client.send(b'hello python')
data = client.recv(1024)
print("recv:",data)
client.close()
  • server
# Author:Li Dongfei
import socket
server = socket.socket()
server.bind(('localhost',6969))  #绑定要监听的端口
server.listen()  #监听
print("开始接收")
conn,addr = server.accept()  #等待接收数据
print(conn,addr)  #conn是客户端连过来而在服务器端为其生成的一个连接实例
print("数据来了")
data = conn.recv(1024)
print("recv:",data)
conn.send(data.upper())
server.close()

发送中文示例

client.send('你好'.encode("utf-8"))

四、实现连续通信

  • client
# Author:Li Dongfei
import socket
client = socket.socket()  #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))

while True:
    msg = input(">>: ")
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print("recv:",data.decode())

client.close()
  • server
# Author:Li Dongfei
import socket
server = socket.socket()
server.bind(('localhost',6969))  #绑定要监听的端口
server.listen()  #监听
print("开始接收")
conn, addr = server.accept()  # 等待接收数据
print("数据来了")
while True:
    data = conn.recv(1024)
    print("recv:",data.decode())
    conn.send(data.upper())
server.close()

五、实现客户端断开服务器不断

  • server
# Author:Li Dongfei
import socket
server = socket.socket()
server.bind(('localhost',6969))  #绑定要监听的端口
server.listen(5)  #监听,最大允许5个连接
while True:
    print("开始接收..")
    conn,addr = server.accept()  # 等待接收数据
    print("数据来了")
    while True:
        data = conn.recv(1024)
        print("recv:",data.decode())
        if not data:
            print("client has lost...")
            break
        conn.send(data.upper())
server.close()
  • client
# Author:Li Dongfei
import socket
client = socket.socket()  #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))

while True:
    msg = input(">>: ")
    if len(msg) == 0:continue
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print("recv:",data.decode())

client.close()

六、ssh服务器和ssh客户端

  • client
# Author:Li Dongfei
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_size = client.recv(1024)  #接收命令结果的长度
    received_size = 0
    #received_data = b''
    while received_size < int(cmd_res_size.decode()):
        data = client.recv(1024)
        received_size += len(data)
        print(data.decode("utf-8"))
    else:
        print("received_size:",received_size)

client.close()
  • server
# Author:Li Dongfei
import socket,os
server = socket.socket()
server.bind(('localhost',9999))
server.listen(5)

while True:
    conn,addr = server.accept()
    print("new conn:",addr)
    while True:
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        print("执行指令: ",data)
        cmd_res = os.popen(data.decode()).read()
        if len(cmd_res) == 0:
            cmd_res = "cmd has no output..."
        conn.send(str(len(cmd_res.encode())).encode("utf-8"))  #先发数据大小给客户端
        conn.send(cmd_res.encode("utf-8"))

server.close()

七、最终版本

  • sock_server_ssh.py
# Author:Li Dongfei
import socket,os
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
    conn, addr = server.accept()
    print("new conn:", 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(str(len(cmd_res.encode())).encode("utf-8"))
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()
  • sock_client_ssh
# Author:Li Dongfei
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_size = client.recv(1024)
    print("命令结果大小",cmd_res_size)
    received_size = 0
    #received_data = b''
    while received_size < int(cmd_res_size.decode()):
        data = client.recv(1024)
        received_size += len(data)
        print(data.decode())
    else:
        print("cmd res receive done.",received_size)
    #cmd_res = client.recv(1024)
    #print(cmd_res.decode())
client.close()

八、socket粘包

        conn.send(str(len(cmd_res.encode())).encode("utf-8"))
        conn.send(cmd_res.encode("utf-8"))

类似以上代码会将两条send的数据放到一个包中发出
解决方法

  • server
# Author:Li Dongfei
import socket,os
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
    conn, addr = server.accept()
    print("new conn:", 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(str(len(cmd_res.encode())).encode("utf-8"))
        client_ack = conn.recv(1024)
        print("ack from client",client_ack.decode())
        conn.send(cmd_res.encode("utf-8"))
        print("send done")
server.close()
  • client
# Author:Li Dongfei
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_size = client.recv(1024)
    print("命令结果大小",cmd_res_size)
    client.send("准备好接受了".encode("utf-8"))
    received_size = 0
    #received_data = b''
    while received_size < int(cmd_res_size.decode()):
        data = client.recv(1024)
        received_size += len(data)
        print(data.decode())
    else:
        print("cmd res receive done.",received_size)
    #cmd_res = client.recv(1024)
    #print(cmd_res.decode())
client.close()

九、ftp server

  1. 读取文件名
  2. 检测文件是否存在
  3. 打开文件
  4. 检测文件大小
  5. 发送文件大小给客户端
  6. 等客户端确认
  7. 开始边读边发数据
  8. 发送md5
  • server
# Author:Li Dongfei
import socket,os,hashlib
server = socket.socket()
server.bind(('localhost',9999))
server.listen()
while True:
    conn, addr = server.accept()
    print("new conn:", addr)
    while True:
        data = conn.recv(1024)
        if not data:
            print("客户端已断开")
            break
        cmd,filename = data.decode().split()
        print(filename)
        if os.path.isfile(filename):
            f = open(filename,"rb")
            m = hashlib.md5()
            file_size = os.stat(filename).st_size
            conn.send(str(file_size).encode())  #send file size
            conn.recv(1024)  #wait for ack
            for line in f:
                m.update(line)
                conn.send(line)
            print("file md5:",m.hexdigest())
            f.close()
            conn.send(m.hexdigest().encode())
        print("send done.")
server.close()
  • client
# Author:Li Dongfei
import socket,hashlib
client = socket.socket()
client.connect(('localhost',9999))
while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0: continue
    if cmd.startswith("get"):
        client.send(cmd.encode())
        server_response = client.recv(1024)
        print("server response",server_response)
        client.send(b"ready to recv file")
        file_total_size = int(server_response.decode())
        received_size = 0
        filename = cmd.split()[1]
        f = open(filename,"wb")
        m = hashlib.md5()
        while received_size < file_total_size:
            if file_total_size - received_size > 1024: #要收不止一次
                size = 1024
            else: #最后一次剩余的数
                size = file_total_size - received_size
            data = client.recv(size)
            received_size += len(data)
            m.update(data)
            f.write(data)
            #print(file_total_size,received_size)
        else:
            new_file_md5 = m.hexdigest()
            print("file recv done.",file_total_size,received_size)
            f.close()
        server_file_md5 = client.recv(1024)
        print("server file md5:",server_file_md5)
        print("client file md5:",new_file_md5)
client.close()

十、socketserver

  • 基本写法
# Author:Li Dongfei
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                if not self.data:  #表示客户端断开
                    print(self.client_address,"断开")
                    break
                self.request.send(self.data.upper())
            except ConnectionResetError as e:
                print("err",e)
                break
if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
    server.serve_forever()
  • client
# Author:Li Dongfei
import socket
client = socket.socket()  #声明socket类型,同时生成socket连接对象
client.connect(('localhost',9999))

while True:
    msg = input(">>: ")
    client.send(msg.encode("utf-8"))
    data = client.recv(1024)
    print("recv:",data.decode())

十一、socket多线程并发

# Author:Li Dongfei
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address[0]))
                print(self.data)
                if not self.data:  #表示客户端断开
                    print(self.client_address,"断开")
                    break
                self.request.send(self.data.upper())
            except ConnectionResetError as e:
                print("err",e)
                break
if __name__ == "__main__":
    HOST, PORT = "localhost", 9999
    server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)  #多线程
    server.serve_forever()

十二、paramiko模块

  • 基于密码ssh连接
# Author:Li Dongfei
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='192.168.56.8', port=22, username='root', password='dongfei')
stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read()
ssh.close()
  • 基于密钥ssh连接
# Author:Li Dongfei
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')
ssh = paramiko.SSHClient()
ssh.connect(hostname='192.168.56.8', port=22, username='root', pkey=private_key)
stdin, stdout, stderr = ssh.exec_command('df')
result = stdout.read()
print(result.decode())
ssh.close()
  • 基于密码sftp传输文件
# Author:Li Dongfei
import paramiko
transport = paramiko.Transport(('192.168.56.8', 22))
transport.connect(username='root', password='dongfei')
sftp = paramiko.SFTPClient.from_transport(transport)
sftp.get('/root/back.sql','back.sql')
transport.close()

181114socke编程的更多相关文章

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. JavaScript之父Brendan Eich,Clojure 创建者Rich Hickey,Python创建者Van Rossum等编程大牛对程序员的职业建议

    软件开发是现时很火的职业.据美国劳动局发布的一项统计数据显示,从2014年至2024年,美国就业市场对开发人员的需求量将增长17%,而这个增长率比起所有职业的平均需求量高出了7%.很多人年轻人会选择编 ...

  3. 读书笔记:JavaScript DOM 编程艺术(第二版)

    读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...

  4. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  5. C#异步编程(一)

    异步编程简介 前言 本人学习.Net两年有余,是第一次写博客,虽然写的很认真,当毕竟是第一次,肯定会有很多不足之处, 希望大家照顾照顾新人,有错误之处可以指出来,我会虚心接受的. 何谓异步 与同步相对 ...

  6. UE4新手之编程指南

    虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程. 新的游戏类.Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写,并且在使用Visual Studio 或 ...

  7. C#与C++的发展历程第三 - C#5.0异步编程巅峰

    系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...

  8. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  9. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

随机推荐

  1. ATL向控件添加私有属性-成员变量

    https://msdn.microsoft.com/zh-cn/library/cc451389(v=vs.71).aspx ------------------------------------ ...

  2. Windows下Git中正确显示中文的设置方法

    Windows下Git中正确显示中文的设置方法 具体设置方法如下: 进入目录etc:$ cd /etc 1. 编辑 gitconfig 文件:$ vi gitconfig.在其中增加如下内容: [gu ...

  3. Redis搭建(三):哨兵模式

    一.sentinel介绍 Redis 2.8中提供了“哨兵”工具来实现自动化的系统监控和故障恢复功能. Redis 2.6 版也提供了哨兵工具,但此时的哨兵是1.0版,存在非常多的问题,任何情况下都不 ...

  4. Java虚拟机(二):垃圾回收算法

    一.介绍 GC(Garbage Collection),垃圾收集 Java中,GC的对象是堆空间和永久区 二.GC算法 1. 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 Java中未使用,使 ...

  5. python子进程模块subprocess详解与应用实例 之一

    subprocess--子进程管理器 一.subprocess 模块简介 subprocess最早是在2.4版本中引入的. subprocess模块用来生成子进程,并可以通过管道连接它们的输入/输出/ ...

  6. libevent源码深度剖析十二

    libevent源码深度剖析十二 ——让libevent支持多线程 张亮 Libevent本身不是多线程安全的,在多核的时代,如何能充分利用CPU的能力呢,这一节来说说如何在多线程环境中使用libev ...

  7. tomcat在linux服务器上部署应用

    连接服务器 服务器地址:xxx.xxx.xxx.xxx 用户名:xxxx 密码:xxxx 进入到服务器中的tomcat路径,关闭服务器,例如 路径:/opt/wzgcyth/apache-tomcat ...

  8. spring 框架jdbc连接数据库

    user=LF password=LF url=jdbc:oracle:thin:@localhost:1521:orcl driver=oracle.jdbc.driver.OracleDriver ...

  9. Python代码注释

    1.单行注释使用# # Code 2.多行注释,成对使用'''或""",三个单撇号或三个双引号 “”” Code “”” 3.多行快捷注释 1).增加注释 选中待注释的多 ...

  10. threading学习

    多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进 ...