python网络基础_socket

利用基本的Socket 通信,模仿远程cmd命令:

Server

import socket
sk = socket.socket()
sk.bind((‘127.0.0.1‘,8090))
sk.listen()

conn,addr = sk.accept()
while True:
    cmd = input(‘cmd : ‘)
    if cmd == ‘q‘:
        conn.send(cmd.encode(‘utf-8‘))
        break
    conn.send(cmd.encode(‘utf-8‘))
    print(‘stdout : ‘,conn.recv(1024).decode(‘gbk‘))
conn.close()
sk.close()

Client

import socket # 内置模块 和os模块的功能有相似之处 能执行操作系统的命令的功能
import subprocess
sk = socket.socket()
sk.connect((‘127.0.0.1‘,8090))
while True:
    cmd = sk.recv(1024).decode(‘utf-8‘)
    if cmd == ‘q‘: break
    res = subprocess.Popen(cmd,shell=True,  # 表示要执行的是一条系统命令
                     stdout=subprocess.PIPE, # 存储执行结果的正常信息
                     stderr=subprocess.PIPE) # 存储执行结果的错误信息
    sk.send(res.stdout.read())
    sk.send(res.stderr.read())
sk.close()

基本的UDP :

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind((‘127.0.0.1‘,8090))
msg,addr = sk.recvfrom(1024)
while True:
    cmd = input(‘cmd : ‘)
    if cmd == ‘q‘:
        sk.sendto(cmd.encode(‘utf-8‘),addr)
        break
    sk.sendto(cmd.encode(‘utf-8‘),addr)
    print(‘stdout : ‘,sk.recvfrom(2048)[0].decode(‘gbk‘))
    print(‘stderr : ‘,sk.recvfrom(2048)[0].decode(‘gbk‘))
sk.close()

import socket
import subprocess
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.sendto(b‘111‘,(‘127.0.0.1‘,8090))
while True:
    cmd = sk.recvfrom(1024)[0].decode(‘utf-8‘)
    if cmd == ‘q‘: break
    res = subprocess.Popen(cmd,shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)
    sk.sendto(res.stdout.read()*100,(‘127.0.0.1‘,8090))
    sk.sendto(res.stderr.read(),(‘127.0.0.1‘,8090))
sk.close()

粘包及简单解决方法:

使用struct模块来转换数据长度。

server:

import socket,struct,json
import subprocess
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加

phone.bind((‘127.0.0.1‘,8080))

phone.listen(5)

while True:
    conn,addr=phone.accept()
    while True:
        cmd=conn.recv(1024)
        if not cmd:break
        print(‘cmd: %s‘ %cmd)

        res=subprocess.Popen(cmd.decode(‘utf-8‘),
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        err=res.stderr.read()
        print(err)
        if err:
            back_msg=err
        else:
            back_msg=res.stdout.read()

        headers={‘data_size‘:len(back_msg)}
        print(headers)
        head_json=json.dumps(headers)
        print(head_json)
        head_json_bytes=bytes(head_json,encoding=‘utf-8‘)
        print(head_json_bytes)

        head = struct.pack(‘i‘,len(head_json_bytes))
        print(struct.unpack(‘i‘,head)[0])
        conn.send(head)      # 先发报头的长度
        conn.send(head_json_bytes) # 再发报头
        conn.sendall(back_msg)  # 在发真实的内容

    conn.close()

 # 服务端:定制稍微复杂一点的报头

client

from socket import *
import struct,json

ip_port=(‘127.0.0.1‘,8080)
client=socket(AF_INET,SOCK_STREAM)
client.connect(ip_port)

while True:
    cmd=input(‘>>: ‘)
    if not cmd:continue
    client.send(bytes(cmd,encoding=‘utf-8‘))

    head=client.recv(4)
    head_json_len=struct.unpack(‘i‘,head)[0]
    head_json=json.loads(client.recv(head_json_len).decode(‘utf-8‘))
    data_len=head_json[‘data_size‘]

    recv_size=0
    recv_data=b‘‘
    while recv_size < data_len:
        recv_data+=client.recv(1024)
        recv_size+=len(recv_data)

    print(recv_size)

    # print(recv_data.decode(‘utf-8‘))
    print(recv_data.decode(‘gbk‘)) #windows默认gbk编码

 # 客户端

练习:up_down   server:

import json
import socket

sk = socket.socket()
sk.bind((‘127.0.0.1‘,8080))
sk.listen()

conn,addr = sk.accept()
content = conn.recv(1024).decode(‘utf-8‘)
content_dic = json.loads(content)
if content_dic[‘operate‘] == ‘upload‘:
    conn.send(b‘received!‘)
    with open(content_dic[‘filename‘],‘wb‘) as f:
        while content_dic[‘filesize‘]:
            file = conn.recv(1024)
            f.write(file)
            content_dic[‘filesize‘] -= len(file)
conn.close()
sk.close()

client:

import os
import json
import socket

sk = socket.socket()
sk.connect((‘127.0.0.1‘,8080))

def get_filename(file_path):
    filename = os.path.basename(file_path)
    return filename

#选择 操作
operate = [‘upload‘,‘download‘]
for num,opt in enumerate(operate,1):
    print(num,opt)
num = int(input(‘请输入您要做的操作序号 : ‘))
if num == 1:
    ‘‘‘上传操作‘‘‘
    #file_path = ‘E:\python10\day33\作业.py‘
    file_path = input(‘请输入要上传的文件路径 : ‘)
    # 告诉对方要上传的文件的名字
    file_name = get_filename(file_path)
    # 读要上传的文件 存成字符串
    with open(file_path,encoding=‘utf-8‘) as  f:
        content = f.read()

    dic = {‘operate‘:‘upload‘,‘filename‘:file_name,‘content‘:content}
    # 将字符串send给server端
    str_dic = json.dumps(dic)
    sk.send(str_dic.encode(‘utf-8‘))
    # server端接收 bytes转码程字符串
    # server端打开文件 写文件
elif num == 2:
    ‘‘‘下载操作‘‘‘
    pass

sk.close()

详细教程参考:http://www.cnblogs.com/Eva-J/articles/8244551.html

subprocess 模块 示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

import subprocess

import os

# ret = os.popen()  # 拿到的结果和错误会连在一起。

# 用法示例

res = subprocess.Popen(‘dir‘,

                 shell=True,

                 stdout=subprocess.PIPE, # 将stdout/stderr 都装入容器

                 stderr=subprocess.PIPE)

print(res.stdout.read().decode(‘gbk‘)) # 可以分开取得结果 和 错误信息

print(res.stderr.read().decode(‘gbk‘))

hmac  模块:

server  在服务端完成验证

import os
import socket
import hmac

secret_key=b‘egg‘
sk = socket.socket()
sk.bind((‘127.0.0.1‘,8080))
sk.listen()

def check_conn(conn):
    msg = os.urandom(32)   # 长度32位的bytes
    conn.send(msg)
    h = hmac.new(secret_key,msg)
    digest= h.digest()   # 加salt后计算的hash结果
    client_digest=conn.recv(1024)
    print(client_digest)
    return hmac.compare_digest(digest,client_digest)

conn,addr = sk.accept()
res = check_conn(conn)
if res:
    print(‘legal‘)
    conn.close()
else:
    print(‘illegal‘)
    conn.close()

sk.close()

client

import socket
import hmac

secret_key=b‘egg‘

sk = socket.socket()
sk.connect((‘127.0.0.1‘,8080))
msg = sk.recv(1024)
h=hmac.new(secret_key,msg)
digest= h.digest()
sk.send(digest)

sk.close()

利用hmac验证客户端的合法性:

import os
import socket
import hmac
def check_client(conn):
    secret_key = b‘egg‘  # 密钥
    send_str = os.urandom(32)
    conn.send(send_str)
    hmac_obj = hmac.new(secret_key,send_str)
    secret_ret = hmac_obj.digest()  # bytes类型
    if conn.recv(1024) == secret_ret:
        print(‘合法的客户端‘)
        return   True
    else:
        print(‘非法的客户端‘)
        return   False

sk = socket.socket()
sk.bind((‘127.0.0.1‘,8090))
sk.listen()

conn,addr = sk.accept()
ret = check_client(conn)
while ret:
    inp = input(‘>>>‘)
    conn.send(inp.encode(‘utf-8‘))
    msg = conn.recv(1024)
    print(msg.decode(‘utf-8‘))
conn.close()
sk.close()

import socket
import hmac
sk = socket.socket()
sk.connect((‘127.0.0.1‘,8090))

recv = sk.recv(1024)
# 用和server端相同的手法对这个字符串进行摘要
secret_key = b‘egg‘  # 密钥
hmac_obj = hmac.new(secret_key,recv)
ret = hmac_obj.digest()
sk.send(ret)
msg = sk.recv(1024)
if msg:
    print(msg.decode(‘utf-8‘))
    while True:
        inp = input(‘>>>‘)
        sk.send(inp.encode(‘utf-8‘))
        msg = sk.recv(1024)
        print(msg.decode(‘utf-8‘))
sk.close()

socketserver 模块:

server

import socketserver

# 类名随意,但必须继承 BaseRequestHandler
class MyServer(socketserver.BaseRequestHandler):
    def handle(self):  # 固定的方法
        self.request.send(b‘hello‘)    # conn
        msg = self.request.recv(1024).decode(‘utf-8‘)
        print(msg)

server = socketserver.ThreadingTCPServer(  # 多线程实现并发
                (‘127.0.0.1‘,9000),
                MyServer)   # 传入写的类

server.serve_forever()  # 永久服务

client

# tcp
    # 粘包
    # 在同一时间只能处理一个客户端的请求
import socket

sk = socket.socket()
sk.connect((‘127.0.0.1‘,9000))
print(sk.recv(1024))

msg = input(‘>>>‘).encode(‘utf-8‘)
sk.send(msg)
sk.close()

login server

import json
import hashlib
import socketserver

def md5_pwd(user,pwd):
    md5_obj = hashlib.md5(user.encode(‘utf-8‘))
    md5_obj.update(pwd.encode(‘utf-8‘))
    ret = md5_obj.hexdigest()
    return ret

def login(userinfo):
    user_dic = json.loads(userinfo)
    passwd = md5_pwd(user_dic[‘username‘], user_dic[‘passwd‘])
    with open(‘userinfo‘) as f:
        for line in f:
            user, pwd = line.split(‘|‘)
            if user_dic[‘username‘] == user and passwd == pwd:
                print(‘登录成功‘)
                break

class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        userinfo = self.request.recv(1024).decode(‘utf-8‘)
        login(userinfo)

server = socketserver.ThreadingTCPServer(
                (‘127.0.0.1‘,9000),
                MyServer)

server.serve_forever()

login client

import json
import socket

ADDR = (‘127.0.0.1‘,9000)

def get_socket():
    sk = socket.socket()
    sk.connect(ADDR)
    return sk

# 输入账号
username = input(‘username >>>‘)
passwd = input(‘password >>>‘)
if username.strip() and passwd.strip():
    sk = get_socket()
    dic = {‘username‘:username,‘passwd‘:passwd}
    str_dic = json.dumps(dic)
    sk.send(str_dic.encode(‘utf-8‘))

sk.close()

采用进程池方式 启用的多进程 socket server

import socket
from multiprocessing import Pool

def func(conn):
    conn.send(b‘gooooood‘)
    print(conn.recv(1024).decode(‘utf8‘))
    conn.close()

if __name__ == ‘__main__‘:
    p = Pool(5)
    sk = socket.socket()
    sk.bind((‘127.0.0.1‘,8081))
    sk.listen()
    while 1:
        conn,addr = sk.accept()
        p.apply_async(func,args=(conn,))  # 异步方式
    sk.close()

import socket

sk = socket.socket()
sk.connect((‘127.0.0.1‘,8081))
ret = sk.recv(1024).decode(‘utf8‘)
print(ret)

msg = input(‘>>>‘).encode(‘utf8‘)
sk.send(msg)
sk.close()
# 客户端用于测试

原文地址:https://www.cnblogs.com/FHBIAO/p/10174528.html

时间: 2024-12-14 08:23:22

python网络基础_socket的相关文章

Python服务器开发二:Python网络基础

Python服务器开发二:Python网络基础 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如

python 网络基础

服务器客户端模式,服务器存在唯一目的是:等待客户的请求, 一.套接字 unix套接字,AF_LOCAL,地址家族,缩写:AF,AF_LOCAL将代替AF_UNIX,很多时候两者等价 基于网络的套接字,AF_INET,AF_INET6 AF_NETLINK,无连接 python只支持AF_UNIX,AF_NETLINK,AF_INET家族 一种面向连接的:tcp协议,SOCK_STREAM 一种面向无连接的:udp协议,SOCK_DGRAM socket创建套接字,语法如下: socket(soc

Python服务器开发 -- 网络基础-乾颐堂

网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/IP协议的封装和应用(程序员层面上).也可以说,TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据. 我们在传输数据时,可以只使用(传输

Python服务器开发 -- 网络基础

Python服务器开发 -- 网络基础 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.... 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.包括:传输层的 FTP,UDP,TCP协议等,网络层的ip协议等,高层协议如HTTP,telnet协议等,HTTP是TCP/IP的一个子协议. socket是对TCP/I

计算机基础系列一:网络基础和python基础(变量和程序交互)7月13和14日课堂预习/随笔/作业

上节课回顾   - 操作系统的两大作用   - 多道技术   一.网络基础   -1.互联网协议---就是计算机的网络通信标准   -2.网络指的是-计算机于计算机 之间通过物理连接介质(网络设备连接到一起二.osi七层协议   -五层为 应用 传输 网络 数据链 物理   2.1-以太网协议规定电信号为一组数据帧  基于Mac地址通讯仅限局域网通信       -每一组帧分为报头head和数据date两部分      -报头长度是固定的包含数据的类型和地址      -规定接入互联网必须要有一

Python网络爬虫基础知识学习

对Python有一些简单了解的朋友都知识Python编程语言有个很强大的功能,那就是Python网络爬虫(http://www.maiziedu.com/course/python/645-9570/),一提到Python,就会想到相关的Python爬虫和scrapy等等,今天就来简单认识学习Python爬虫的基础知识,有了一定的相关爬虫知识,以后学习scrapy.urllib等等知识时,会相对轻松些. 爬虫: 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组

python网络编程基础--socket的简介,以及使用socket来搭建一个简单的udp小程序

socket介绍: socket(简称套接字),是进程间通讯的一个工具,他能实现把数据从一方传输到另一方,完成不同电脑上进程之间的通讯,它好比数据的搬运工.socket应用:不夸张来说,只要跟网络相关的应用程序或者软件都使用到了socket, 比如:微信,qq等使用socket创建udp网络程序的流程:1,创建客户端套接字2,发送/接收数据3,关闭套接字使用程序展现流程 :(使用的 ide为pycharm):1,首先创建socket,在 Python 中 使用socket 模块的函数 socke

python网络编程基础(线程与进程、并行与并发、同步与异步)

python网络编程基础(线程与进程.并行与并发.同步与异步) 目录 线程与进程 并行与并发 同步与异步 线程与进程 进程 前言 进程的出现是为了更好的利用CPU资源使到并发成为可能. 假设有两个任务A和B,当A遇到IO操作,CPU默默的等待任务A读取完操作再去执行任务B,这样无疑是对CPU资源的极大的浪费.聪明的老大们就在想若在任务A读取数据时,让任务B执行,当任务A读取完数据后,再切换到任务A执行.注意关键字切换,自然是切换,那么这就涉及到了状态的保存,状态的恢复,加上任务A与任务B所需要的

PYTHON网络编程基础 pdf扫描版高清下载

PYTHON网络编程基础 pdf,本书全面介绍了使用PYTHON进行网络编程的基础知识,高级网络操作.WebServices.解析HTML和XHTML.XML.FTP.使用PYTHON操作数据库.SSL.几种服务器端框架,以及多任务处理等,实用性比较强,书中提供了175个实例,6600行以上的代码. 目录 第1部分 底层网络 第1章 客户/服务器网络介绍 第2章 网络客户端 第3章 网络服务器 第4章 域名系统 第5章 域名系统 第2部分 Web Service 第6章 Web客户端访问 第7章