zoukankan      html  css  js  c++  java
  • Socket简单实现ssh笔记

    1. Scoket概念:

      socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 我们知道网络 通信 都 是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。 建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。(利用IP和端口实现两个设备的通信)。
    2. Socket核心方法:

      接收端:
      import socket
      socket.TCP/IP
      listen(ip,port)
      waiting()#等待数据
      recv()#接收数据
      send()#再发送数据
      发送端:
      import socket
      socket.TCP/IP
      connect(a.ip,a.port)#接受端主机的IP,端口(port:端口号)
      socket.send(hello)#发送的数据sendall()名义上是一次性发送所有的数据,但是由于系统原因还是有限制的
      socket.recv()#接收数据
      socket.close()#关闭
    3. 实例列举:

      服务器端:
      import socket
      server=socket.socket()#设置连接
      server.bind((“localhost”,8888))#绑定连接(参数是一个元组)
      server.listen(5)#监听
      conn,addr=server.accept()#等待
      data=conn.recv(1024)#接收(是byte类型的,需要转换(一般编为utf-8))
      conn.sendall(data)#一次性发送所有数据(由于系统原因,是发送不了所有的数据的)
      server.close()
      客户端:
      import socket
      client=socket.socket()
      client=connect((“localhost”,8888))#建立连接,参数是一个元组
      data=input().strip()#手工输入的是unicode类型,但是再传输的时候是要编码的
      client.send(data.encode(“utf-8”))#发送数据
      data=client.recv(1024)#收到的数据是utf-8编码的,所以直接输出是乱码
      client.close()





    4. 粘包:

      当你连续的调用send()时,由于接收时recv()有大小限制,会发生发送的数据量大于接收的数据量,导致接收的数据不是你期待的数据,这个时候就发生了粘包(两次发送的数据被同一次接收) 为了避免这种错误,我们通常会设计反馈,即你发送一次数据,我们会吧发送的数据反馈给发送给你。这样两次发送中间夹杂着一次接收,避免了数据在缓冲中导致粘包。
    5. 一些注意的地方:

    • 发送与接收的类型:

             我们在Python3中,默认是Unicode,而在发送数据(send)时,函数send()的参数类型是:Byte,所以我们要进行数据的转换:

    str==>bytes bytes==>str

    a=”qweqwe”  =>a的类型为str

    str==>bytes

    b=a.encode(“utf-8”)

    b=b”hello word”  =>b为bytes类型

    bytes==>str

    s=b.decode(“utf-8”)

    • 数据的校验:

    字符串类型的,我们可以利用hashlib包中的md5算法来检验

    文件类型的,我们可以对比两个文件的区别:

    diff file1 file2

    观察两个文件是否一致(文件检测)

    SocketServer:

    这个比较方便,它集成了一些东西,很方便的,只是server端改变了一下书写方式,客户端不用改变

    代码如下:

    #this is server
    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))
                    print(self.data)
                    self.request.send(self.data.upper())
                except ConnectionResetError as e:
                    print("error: ",e)
                    break
    if __name__ =="__main__":
        HOST,PORT="localhost",9999#声明IP与端口
        server=socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)#设置连接
        server.serve_forever()#建立连接,然后系统在连接成功以后会自动调用函数handle()
    #this is client
    import socket
    client=socket.socket()
    client.connect(("localhost",9999))
    while True:
        cmd=input(">>").strip()
        if cmd =="":
            continue
        client.send(cmd.encode())
        data=client.recv(1024)
        print(data)

    附:

    socket一个最简单的通信:

    #服务器端:
    import socket
    server=socket.socket()
    server.bind(("localhost",8888))
    server.listen()
    conn,addr=server.accept()
    count=10
    while count:
        data=conn.recv(1024)
        print(data.decode("utf-8"))
        conn.send(data)
        count-=1
    server.close()
    #客户端
    import socket
    client=socket.socket()
    client.connect(("localhost",8888))
    while True:
        chioce=input(">>").strip()
        client.sendall(chioce.encode("utf-8"))
        data=client.recv(1024)
        if not data:
            break
        print(data.decode("utf-8"))
    client.close()
  • 相关阅读:
    C# linq根据属性分组,并累加计算
    AR模板分组显示(C#打印)
    显示单据信息(类似打印)
    C#同步方法中调用异步方法
    win10 Git安装或者使用出现128问题
    简单的分页查询实现
    数据库批量插入【数据库】
    VideoView
    音乐播放
    画画板案例
  • 原文地址:https://www.cnblogs.com/Anxc/p/11032328.html
Copyright © 2011-2022 走看看