python网络编程linux_python学习之网络编程

一、socket模块

socket模块提供了底层的接口,通过socket模块可以实现不同计算机的通信

ip+port定位了计算机中应用程序的具体位置,socket绑定ip+port来建立链接,socket的方法详情:

socket(family, type, proto): socket函数创建一个socket对象,使用socket对象创建连接,

family协议族,默认AF_INET,ipv4协议,type,socket类型,proto协议类型

bind((ip, port)): 绑定服务器地址

listen(n): 监听socket创建的链接, n代表指定连接队列数,

connect(('127.0.0.1', 8080)): 连接到服务端

accept():等待客户端连接,返回连接对象和客户端ip组成的元组

recv(n): 接收数据,n代表接受固定的数据

send(data): 发送数据

例子:模拟客户端服务端通信

server:

#!/usr/bin/python

# --*-- coding: utf-8 --*--

import socket

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

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

phone.listen(5)

print('starting...')

conn, addr = phone.accept()

print(conn)

print('client addr: ', addr)

print('ready to read msg')

client_msg = conn.recv(1024)

print('client msg: %s' %(client_msg))

conn.send(client_msg.upper())

conn.close()

phone.close()

client

#!/usr/bin/pytthon

# --*-- coding: utf-8 --*--

import socket

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

phone.connect(('127.0.0.1', 8080))

phone.send('hello'.encode('utf-8'))

back_msg = phone.recv(1024)

print(back_msg.decode('gbk'))

phone.close()

模拟循环发送接收数据

server

import socket

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

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

phone.listen(5)

while True:

print('starting...')

conn, addr = phone.accept()

print('client addr ', addr)

while True:

try:

client_msg = conn.recv(1024)

if not client_msg: break

print('client_msg: %s' %client_msg)

conn.send(client_msg.upper())

except Exception:

break

conn.close()

phone.close()

client

import socket

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

phone.connect(('127.0.0.1', 8080))

while True:

msg = input(">>: ")

if not msg: continue

phone.send(msg.encode('utf-8'))

back_msg = phone.recv(1024)

print(back_msg.decode('utf-8'))

phone.close()

模拟远程执行命令,并返回结果

server

import socket

import subprocess

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

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

phone.listen(5)

while True:

print('starting...')

conn,addr = phone.accept()

print('client addr: ', addr)

while True:

try:

cmd = conn.recv(1024)

if not cmd: break

res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

err = res.stderr.read()

if err:

cmd_res = err

else:

cmd_res = res.stdout.read()

conn.send(cmd_res)

except Exception:

break

conn.close()

phone.close()

client

import socket

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

phone.connect(('127.0.0.1', 8080))

while True:

cmd = input('>>: ').strip()

if not cmd: continue

phone.send(cmd.encode('utf-8'))

back_msg = phone.recv(1024)

print(back_msg.decode('gbk'))

phone.close()

粘包现象,数据包无规则断开,出现不希望的断开现象

server

from socket import *

import time

tcp_server = socket(AF_INET, SOCK_STREAM)

tcp_server.bind(('127.0.0.1', 8080))

tcp_server.listen(5)

conn, addr = tcp_server.accept()

res1 = conn.recv(5)

res2 = conn.recv(5)

res3 = conn.recv(7)

print(res1.decode('gbk'))

print(res2.decode('gbk'))

print(res3.decode('gbk'))

client

from socket import *

import time

tcp_client = socket(AF_INET, SOCK_STREAM)

tcp_client.connect(('127.0.0.1', 8080))

tcp_client.send('hello world'.encode('utf-8'))

time.sleep(5)

tcp_client.send('egon666'.encode('utf-8'))

解决粘包问题,使用struct模块,打包数据并解包数据

例子:

server

import socket

import subprocess

import struct

import json

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

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

phone.listen(5)

while True:

print('starting...')

conn, addr = phone.accept()

print('client addr: ', addr)

while True:

try:

cmd = conn.recv(1024)

if not cmd:break

res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

err = res.stderr.read()

if err:

cmd_res = err

else:

cmd_res = res.stdout.read()

head_dict = {'filename': None, 'hash': None, 'total_size': len(cmd_res)}

head_json = json.dumps(head_dict)

head_bytes = head_json.encode('utf-8')

print(struct.pack('i', len(head_bytes)))

conn.send(struct.pack('i', len(head_bytes)))

conn.send(head_bytes)

conn.send(cmd_res)

except Exception:

break

conn.close()

phone.close()

client

import socket

import struct

import json

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

phone.connect(('127.0.0.1', 8080))

while True:

cmd = input('>>: ').strip()

if not cmd: continue

phone.send(cmd.encode('utf-8'))

head_struct = phone.recv(4)

#print(head_struct)

head_len = struct.unpack('i', head_struct)[0]

head_bytes = phone.recv(head_len)

head_json = head_bytes.decode('utf-8')

#print(head_json)

head_dict = json.loads(head_json)

#print(head_dict)

total_size = head_dict['total_size']

recv_size = 0

data = b''

while recv_size 

recv_data = phone.recv(1024)

data += recv_data

recv_size += len(recv_data)

print(data.decode('gbk'))

phone.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值