首页 > 代码库 > **.Python自学之路:网络编程

**.Python自学之路:网络编程

socket

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

技术分享

1.首先来看一下简易版的客户端与服务器的搭建

客户端

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

import socket

ip_port = (127.0.0.1,9999)                   #测试地址与端口

sk = socket.socket()                                #生成句柄
sk.connect(ip_port)                                 #连接服务器


sk.sendall(bytes(...connecting..., utf8)) #python3中以字发送数据
server_reply = sk.recv(1024)                  #接收来自服务器的数据                  

print(str(server_reply, utf8))                  #输出时用字符串形式

sk.close()

服务器

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

import socket

ip_port = (127.0.0.1, 9999)
sk = socket.socket()    #生成句柄
sk.bind(ip_port)        #绑定ip地址和端口
sk.listen(5)            #监听,5为最大连接个数

while True:
    print(...server waiting...)
    conn, addr = sk.accept()   #阻塞待连,生成实例conn,并返回实例和地址

    client_data = conn.recv(1024)  #接收实例的数据,1024个字符
    print(str(client_data, utf8))
    conn.sendall(bytes(...connect successfully...,utf8))#服务器发回的数据

    conn.close()

 

2.改进:以上例子只能实现一次性通信,我们改进的动机是想要完成一个类似于QQ聊天的交互式通信

客户端

import socket
ip_port = (127.0.0.1,9999)  
sk = socket.socket()
sk.connect(ip_port)  


sk.sendall(bytes(请求通讯, utf8))
server_reply = sk.recv(1024)

print(str(server_reply, utf8))
while True:                #交互式通信
    userInput = input(">>:").strip()
    sk.send(bytes(userInput, utf8))
    server_reply = sk.recv(1024)
    print(str(server_reply, utf8))
    
sk.close()

服务器

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

import socket

ip_port = (127.0.0.1, 9999)

sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
    print(server waiting...)
    conn, addr = sk.accept()

    client_data = conn.recv(1024)
    print(str(client_data, utf8))
    conn.sendall(bytes(连接成功, utf8))
    while True:
        client_data = conn.recv(1024)
        print(str(client_data, utf8))
        server_response = input("\033[32;1m>>:\033[0m").strip()
        conn.send(bytes(server_response))
    conn.close()

 

3.改进:实现服务器在多连接情况下异常处理

客户端

import socket
ip_port = (127.0.0.1, 9999)

sk = socket.socket()
sk.connect(ip_port)


sk.sendall(bytes(请求通讯, utf8))
server_reply = sk.recv(1024)

print(str(server_reply, utf8))
while True:
    userInput = input(">>:").strip()
    sk.send(bytes(userInput, utf8))
    server_reply = sk.recv(1024)
    print(str(server_reply, utf8))

sk.close()

服务器

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

import socket

ip_port = (127.0.0.1, 9999)

sk = socket.socket() 
sk.bind(ip_port) 
sk.listen(5) 

while True:
    print(server waiting...)
    conn,addr = sk.accept()   

    client_data = conn.recv(1024)  
    print(str(client_data, utf8))
    conn.sendall(bytes(不要回答,不要回答,不要回答,utf8))
    while True:
        try:
            client_data = conn.recv(1024)
            print(str(client_data,utf8))
        except Exception:
            print("Connection break!!!")
            break
        conn.send(client_data)
    conn.close()

# while True:     Linux version
#     client_data = http://www.mamicode.com/conn.recv(1024)
#     print("recv:",str(client_data,‘utf8‘))
#     if not client_data:break
#     conn.send(client_data)

 

4.在Linux上实现SSH的通讯:解决大数据的传输

技术分享

 

客户端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = (127.0.0.1,9999)

sk = socket.socket()
sk.connect(ip_port)

while True:
    user_input = input("cmd>>:").strip()
        if len(user_input) == 0:continue
        if user_input == q:break
        sk.send(bytes(user_input,utf8))
        #ack_msg = b"CMD_RESULT_SIZE|%s" % len(cmd-result)
        server_ack_msg = sk.recv(100)
        cmd_res_msg = str(server_ack_msg).split("|")
        if cmd_res_msg[0] == "CMD_RESULT_SIZE":
                cmd_res_size = int(cmd_res_msg[1])
                sk.send(b"CLIENT_READY_TO_RECV")
        res = ‘‘
        rec_size = 0
        while rec_size <= cmd_res_size:
                data = sk.recv(500)
                rec_size += len(data)  #实际大小
                res += str(data.decode())
        else:
                print(str(res))
                 print("......recv done....")
sk.close()

服务端:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
import time
import subprocess
ip_port = (127.0.0.1, 9999)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
    print(server waiting...)
    conn,addr = sk.accept()
    while True:
           client_data = conn.recv(1024)
           if not client_data:break
           print("recv:", str(client_data, utf8))
           cmd = str(client_data,"utf8").strip()
           cmd_call = subbprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE)

           cmd_result = cmd_call.stdout.read()
           if len(cmd_result) == 0:
                cmd_result = b"cmd execution has no output.."
           ack_msg = b"CMD_RESULT_SIZE|%s" % len(cmd_result)
           conn.send(ack_msg)
           conn.recv(10) #生成阻塞,分割两次发送,避免,两次分开的数据一起发出去了。
           if client_ack.decode() == CLENT_READY_TO_RECV:
                   conn.send(cmd_result) #但这种方法,cpu浪费了大量的时间
conn.close()

 

**.Python自学之路:网络编程