首页 > 代码库 > 一个初学者的辛酸路程-socket编程-8

一个初学者的辛酸路程-socket编程-8

前言:

你会发现会网络是多么幸福的事情

主要内容:

socket 概念:

socket本质上就是2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。我们知道网络通信都是基于IP地址加短裤的方法来定位到目标的具体机器上的具体服务。操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果把一个公司比做一台电脑,那公司的总机号码就相当于IP地址,每个员工的分机号就相当于短裤,你想找公司某个人,必须先打电话到总机,然后再转分机。

这里提到了OSI七层模型的概念:

第一层:物理层    

第二层:数据链路层

第三层: 网络层

第四层:传输层

第五层:会话层

第六层:表示层

第七层:应用层

 

建立一个socket必须至少有2端,1个是服务端,1个是客户端,服务端被动等待并接受请求,客户端主动发起请求,连接建立之后,双方可以互发数据。

建立一个链接,需要IPV4和IPV6
Socket Types
socket.SOCK_STREAM     #for tcp
socket.SOCK_DGRAM     #for  udp
socket.SOCK_RAW      #原始套接字
建立链接之后,就需要IP和端口了
技术分享
排队数量,一般是5
sk.listen(backlog)
关闭套接字
sk.close()
接受套接字的数据
sk.recv(bufsize[,flag])
 
具体步骤
1、生成一个socket实例
 
server = socket.socket(AF_INET,SOCK_STREAM)
2、绑定地址
server.bind(‘0.0.0.0‘,8000)
3、监听端口排队5个
server.listen(5)
 
4、接受
talk_list = []
server.accept()   会返回2个值 conn 建立链接的线   client_addr 链接对象
talk_list.append(conn)
conn.send(‘sdfds‘) 
另外一个介入进来
conn.recv(‘sdfsf‘)
5、发送
server.send()
6、关机
server.close()
 
上面是服务端
 
客户端通信
client = socket.socket(AF_INET,SOCK_STREAM)
client.connect(‘‘)
client.send
client.recv
 
接下来,就通过代码来实现这个服务端和客户端
server端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind(("0.0.0.0",8000))

server.listen(5)

conn,client_addr = server.accept()

print(conn,client_addr)

while True:
    data = conn.recv(1024)  #1024字节
    print("recv from cli:",data)
    conn.send(b"got it")

client端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

client = socket.socket()

client.connect(("localhost",8000))
while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode())
    print("send ",msg)
    data = client.recv(1024)
    print("receive from server:",data)
再开一个client的时候,会出现堵死的情况,断开一个,另外一个可以使用了。
所以上面的可以改良
 
server端
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind(("0.0.0.0",8000))

server.listen(5)

while True:
    conn,client_addr = server.accept()
    print(conn,client_addr)

    while True:
        try:
            data = conn.recv(1024)  #1024字节
            print("recv from cli:",data)
            conn.send(b"got it")
        except ConnectionResetError as e:
            print(e)
            break

客户端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

client = socket.socket()

client.connect(("localhost",8000))
while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode())
    print("send ",msg)
    data = client.recv(1024)
    print("receive from server:",data)

接着写一个SSH连过去,执行命令的服务端和客户端

server端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket
import subprocess

server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

server.bind(("0.0.0.0",8000))

server.listen(5)
print("=============start to listen============")
while True:
    conn,client_addr = server.accept()
    print(conn,client_addr)

    while True:
        
            data = conn.recv(1024)  #1024字节
            print("recv from cli:",data)
            res_obj = subprocess.Popen(data,shell=True ,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            res = res_obj.stdout.read()
            conn.send(str(len(res)).encode())
            print("==res len:",len(res))
            conn.send(res)
            

客户端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

client = socket.socket()

client.connect(("localhost",8000))
while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode())
    print("send ",msg)

    data = client.recv(1024)
    print("res:",data.decode())
    res_len = int(data.decode())

    recevied_size = 0
    res = b‘‘
    while recevied_size < total_size:
        d = client.recv(1024)
        res += d

        recevied_size += len(d)
    print(res.decode())

最后做一个持续接受的server端和client端

服务端

[root@docker20-127 ~]# cat server.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket
import subprocess
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("0.0.0.0",8007))
server.listen(5)
print("--------------start to listen------------------")

while True:
    conn,client_addr = server.accept()
    print(conn,client_addr)

    while True:
            data = conn.recv(1024) 
            print("recv from cli:",data)
            res_obj = subprocess.Popen(data,shell=True, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            res = res_obj.stdout.read()
            conn.send(str(len(res)).encode())
            print("--res len:",len(res))
            conn.send(res)

客户端

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Author: Leon xie

import socket

client = socket.socket()

client.connect(("10.10.20.127",8005))

while True:

    msg = input(">>:").strip()
    if len(msg) == 0:continue

    client.send(msg.encode())
    print("send",msg)
    data = client.recv(1024)
    print("res:",data.decode())
    total_size = int(data.decode())
    #总长度跟已经收到的相等即可

    received_size = 0
    res=b‘‘
    while  received_size <total_size:
        d = client.recv(1024)
        res += d

        received_size += len(d)

    print("---------------rece done------------")
    print(res.decode())

完结。

 

一个初学者的辛酸路程-socket编程-8