您的位置:首页 > 编程语言 > Python开发

Python实现SocketServer(一)

2017-11-03 17:44 363 查看

说明

TCP 服务器是web后端开发必须学习的一环,此文章记录了我个人在学习python web开发过程中开发SocketServer的流程

Socket通信流程



网上找的图

逐步实现SocketServer

实现单次Soket Server与Client逻辑

依照以上述逻辑,使用python 标准库socket 模块实现单次接收/发送的Server/Client.

注:开始未将代码写成类是应为个人觉得OOP主要用来复用代码、解耦、抽象化复杂对象,对于第一步来说,使用类反而会让整个TCPServer创建流程不够直观。因此我会在后面需要的步骤将其重构为类

socket构造参数

参数含义
family默认为AF_INET协议簇,指定socket使用的协议,默认使用IPv4协议簇
type默认值未SOCKET_STREAM指定套接字类型,默认为流式套接字
proto默认值为0指定套接字使用协议簇中的哪个协议,默认为TCP协议
fileno默认值为None指定socket打开的文件描述符

socket常用方法

方法参数含义
bind()address绑定socket到特点的ip和port上,形式为(‘127.0.0.1’, 80)
listen()开始监听请求
accept()接收请求,在未收到请求时阻塞
send()bytes、flags(可选)发送二进制数据,flags是一系列标志,可以控制发送的行为
rcev()buffersize, flags(可选)指定接收缓冲区的大小,flags可控制接收行为
其他的方法不列举了,以后用到在写.

Code

Client Code

#!/usr/bin/env python3
# encoding: utf-8

from socket import socket, AF_INET, SOCK_STREAM

def client(server_addr, msg):
"""
This function is a simple client to connect to TCPserver.

Args:
server_addr: String of Server IP address.
msg: The message that you want to send to server.It't type can
be str or bytes
"""
with socket(AF_INET, SOCK_STREAM) as sock  # TCP/IPv4 Socket
sock.connect(server_addr)
if not isinstance(msg, bytes):
msg = bytes(msg, 'utf-8')
sock.send(msg)
data = sock.recv(4096)
print(data.decode('utf-8'))

if __name__ == '__main__':
client(('127.0.0.1', 8080), "I'm client.")


ServerCode

#!/usr/bin/env python3
# encoding: utf-8
from socket import socket as Socket, AF_INET, SOCK_STREAM
from sys import exit, stderr
import logging

logging.basicConfig(
level=logging.INFO,
stream=stderr,
format="[%(levelname)s] %(asctime)s %(message)s"
)
log = logging.getLogger('SocketServer')

def check_addr(address):
"""
Check server address format
Not complete. TODO
"""
# check address
if len(address) < 2:
exit("You miss ip address or port.")
ip_addr, port = address

# Check port format
if isinstance(port, str):
try:
port = int(port)
except ValueError:
exit("Error Port Number: %s" % port)
return (ip_addr, port)

def recv_msg(socket):
"""Receive message from client"""
data = socket.recv(4096)
if isinstance(data, bytes):
data = data.decode('utf-8')
log.info("The receive data from client is: %s", data)

def send_msg(socket, msg):
"""Send message to client"""
socket.send(bytes(msg, 'uft-8'))
log.info("Send '%s' to client", msg)

def server(address=None, *, ip_addr=None, port=None):
"""
This is a simple TcpServer.It can receive data once from client.

Args:
ip_addr: String of ip address which server bind.
port: The port number which server bind. Type can be int or str.
address: Tuple like ('127.0.0.1', 80). Contain ip_addr and port. If
you use ip_addr or port with address param, it will override these.
"""
if not address:
address = (ip_addr, port)
address = check_addr(address)

with Socket(AF_INET, SOCKET_STREAM) as socket:
socket.bind(address)
s, _ = socket.accept()
recv_msg(s)
send_msg(s, 'Hello')

log.info("The Tcp Server close.")

if __name__ == "__main__":
server(('127.0.0.1', 8080))


接下来的计划

下面这些问题将在下一篇文章中解决

- 实现服务端接收多个client访问

- 当server处理程序消耗时间长时提高server处理效率
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python