博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

python socket

Posted on 2016-03-09 13:31  善恶美丑  阅读(209)  评论(0编辑  收藏  举报
Socket

 

 

 

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)

socket和file的区别:

  • file模块是针对某个指定文件进行【打开】【读写】【关闭】
  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

     利用socket实现简单双人对话场景

    import socket
    
    ip_port = ('127.0.0.1',9999)
    
    sk = socket.socket()
    sk.bind(ip_port)
    sk.listen(5)   # 最大允许连接5个?
    
    while True:
        print ('server waiting...')
        conn,addr = sk.accept()  ##等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例
        while True:
            try:
                client_data = conn.recv(1024) # 阻塞状态 接受客户端的数据 1024代表字节
                # if not client_data.decode():break
                print (str(client_data,'utf-8'))
                A=input('>>>:')
                conn.sendall(bytes(bytes(A,'utf8')))
            except Exception:
                print("error")
                break
    socket server
    import socket
    ip_port = ('127.0.0.1',9999)
    
    sk = socket.socket()
    sk.connect(ip_port)
    while True:
        user_input = input('>>:'.strip())
        sk.sendall(bytes(user_input,'utf-8'))
        server_reply = sk.recv(1024)
        print (str(server_reply,'utf-8'))
    socket client

     注意 上面socket server 的recv接受的不是字节 是字符

 通过socket实现ssh的功能以及大数据的传输:

# 一些简单的命令,可直接通过socket传入,如果一些返回结果数据较多的命令,不做处理的话,返回的消息就会错乱

linux_socket_server

#!/usr/bin/env python3.5
# Auth -chenjinpeng-
import socket,subprocess,time

Ip_port = ('127.0.0.1',9999)

Ftp = socket.socket()
Ftp.bind(Ip_port)
Ftp.listen(5) # 最大允许连5个?

while True:
        print ("server waiting...")
        conn,addr = Ftp.accept() #等待用户连接操作,addr表示获取客户端的ip和端口 conn表示生成实例

        while True:
                #try:
                client_data = conn.recv(1024) # 收客户端的消息 阻塞
                if not client_data:break # 如果接受不到消息 则退出循环
                cmd = client_data.decode().strip() # 将获取到的消息进行转码,将bytes转换为str用decode
                cmd_call = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE) # 将读取到的命令通过管道符进行输出到变量
                #Server_input = input("S >>>:").strip()
                cmd_result = cmd_call.stdout.read() # 获取命令的结果(此执行结果为bytes类型)
                if len(cmd_result) == 0:
                        cmd_result = b"cmd execution has no output!"
                cmd_len=bytes(str("cmd_long|%s"%str(len(cmd_result))),'utf8')  # 第一次首先将结果的长度发过去
                conn.sendall(cmd_len)
                ack=conn.recv(50) # 确认用户收到后回复。进行下一步操作
                if ack:
                        if ack.decode() == "ack":
                                conn.sendall(cmd_result) # 因为为bytes类型 直接发送
                else:break
        conn.close()

linux_csocket_client

#!/usr/bin/env python3.5
# - Auth chenjinpeng -

import socket
Ip_port = ('127.0.0.1',9999)

Client = socket.socket()
Client.connect(Ip_port)

#Client.sendall(bytes('请求占领地球','utf8'))
#Server_reply = Client.recv(1024)
#print (str(Server_reply,'utf8'))
while True:
        User_input = input(">>>:").strip()
        if len(User_input) == 0:continue
        if User_input == 'q':break

        Client.sendall(bytes(User_input,'utf8'))
        cmd_result_msg=Client.recv(100) # 第一次接受的是服务器发来的字符串长度
        cmd_result_len=str(cmd_result_msg.decode()) # 转换str
        cmd_result_len_result=cmd_result_len.split("|") # 分割列表
        if cmd_result_len_result[0] == "cmd_long": # 判断是否是分割的数据
                cmd_result_size = int(cmd_result_len_result[1]) # 取出返回的字符长度
        else:
                print ("error !")
                continue
        Client.sendall(bytes("ack",'utf8')) # 发送ack确认消息,服务端正式开始发送数据
        cmd_len_default=0 # 定义输出读取的字符长度
        res = '' # 定义空字符 循环增加每次读取的字符
        while cmd_len_default < cmd_result_size: # 判断字符是否读完。如果小于服务端发送过来的长度,则代表没接收完
                Server_reply = Client.recv(500) # 每次收取500字符
                cmd_len_default+=len(Server_reply) # 每次字符长度加上已经读取的字符长度
                res += str(Server_reply.decode()) # 读取过的字符相加,循环完毕后统一打印
        else:
                print (res)
                print ("-------last time-----")
Client.close()