Python网络编程——编写一个简单的回显客户端/服务器应用
今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端。采用python3.5版本,在注释中会标明python2和python3的不同之处。
1.代码
(1)服务器端及对应代码解释
- # ! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # 编写回显服务器
- import socket
- import sys
- import argparse
- # 定义常量
- host = 'localhost'
- data_payload = 2048
- backlog = 5
- def echo_server(port):
- # 创建一个TCP socket
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- # 设置TCP套接字关联选项——重用地址
- sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- # 建立套接字端口
- server_address = (host, port)
- print("Starting up echo server on %s port %s" % server_address)
- # 将socket绑定到server_address地址
- sock.bind(server_address)
- # 监听客户端
- # backlog指定最多允许多少个客户连接到服务器。它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
- # 这里设定为5
- sock.listen(backlog)
- # 在调用 Listen 之前,必须首先调用 Bind 方法,否则 Listen 将引发 SocketException。
- while True:
- print("Waiting to receive message from client")
- # 调用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。
- # accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection
- # 是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
- client, address = sock.accept()
- # 指定data最大长度为2048字节
- data = client.recv(data_payload)
- if data:
- print("Data: %s" % data)
- client.send(data)
- print("sent %s bytes back to %s" % (data, address))
- # 关闭连接
- client.close()
- if __name__ == '__main__':
- # 创建一个解析对象,其中描述为"Socket Error Examples"
- parser = argparse.ArgumentParser(description='Socket Server Example')
- # 采用add_argument方法
- # name or flags —— 必须的参数,该参数接收选项参数或者是位置参数
- # action:
- # (1)store —— 默认action模式,储存值到指定变量
- # (2)store_const —— 储存值在参数的const部分指定,多用于实现非布尔的命令行flag
- # (3)store_true/store_false —— 布尔开关。可以2个参数对应一个变量
- # (4)append —— 储存值到列表,储存值在参数的const部分指定
- # (5)append_const —— 储存值到列表,储存值在参数的const部分指定
- # (6)version —— 输出版本信息然后退出
- # type —— 把从命名行输入的结果转成设置的类型,通常用来检查值的范围,以及合法性。默认string
- # required —— 指定某个选项在命名中出现, 默认False, 若为 True, 表示必须输入该参数
- # dest —— 把位置或者选项关联到一个特定的名字
- parser.add_argument('--port', action="store", dest="port", type=int, required=True)
- # 调用parse_args()方法进行解析
- given_args = parser.parse_args()
- port = given_args.port
- echo_server(port)
- def bind(self, address): # real signature unknown; restored from __doc__
- """
- bind(address)
- Bind the socket to a local address. For IP sockets, the address is a
- pair (host, port); the host must refer to the local host. For raw packet
- sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
- """
- pass
- def listen(self, backlog=None): # real signature unknown; restored from __doc__
- """
- listen([backlog])
- Enable a server to accept connections. If backlog is specified, it must be
- at least 0 (if it is lower, it is set to 0); it specifies the number of
- unaccepted connections that the system will allow before refusing new
- connections. If not specified, a default reasonable value is chosen.
- """
- pass
服务器端代码
(2)客户端及对应代码解释
- # ! /usr/bin/env python
- # -*- coding: utf-8 -*-
- # 编写回显客户端
- import socket
- import sys
- import argparse
- host = 'localhost'
- def echo_client(port):
- # 创建TCP socket连接
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- # 获取服务器端host和端口号
- server_address = (host, port)
- print("Connecting to %s port %s" % server_address)
- sock.connect(server_address)
- try:
- # 将message内容发送到服务器端
- message = "Test message, This will be echoed"
- print("Sending %s" % message)
- # python2和python3此处不同
- # python2—— sock.sendall(message)
- # sendall()发送完整的TCP数据,成功返回None,失败抛出异常
- sock.sendall(message.encode())
- # 服务器端将发送的数据回传给客户端并打印
- amount_received = 0
- amount_expected = len(message)
- while amount_received < amount_expected:
- data = sock.recv(1024)
- amount_received += len(data)
- print("Received: %s" % data)
- # 处理相对应错误
- except socket.error as e:
- print("socket error: %s" % str(e))
- except Exception as e:
- print("Other exception: %s" % str(e))
- finally:
- print("Closing connection to the server")
- sock.close()
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Socket Server Example')
- parser.add_argument('--port', action="store", dest="port", type=int, required=True)
- given_args = parser.parse_args()
- port = given_args.port
- echo_client(port)
客户端代码
(3)运行结果
- 1. 服务器端
- Abel$ python3 1_13a_echo_server.py --port=9900
- Starting up echo server on localhost port 9900
- Waiting to receive message from client
- 2.客户端发送数据时,服务器端
- Data: b'Test message, This will be echoed'
- sent b'Test message, This will be echoed' bytes back to ('127.0.0.1', 62389)
- Waiting to receive message from client
- 3.客户端
- Abel$ python3 1_13b_echo_client.py --port=9900
- Connecting to localhost port 9900
- Sending Test message, This will be echoed
- Received: b'Test message, This will be echoed'
- Closing connection to the server
Python网络编程——编写一个简单的回显客户端/服务器应用的更多相关文章
- python2.7_1.14_编写一个简单的回显客户端/服务器应用
1.服务端 server.py # -*- coding: utf-8 -*- import socket import argparse host = 'localhost' data_payloa ...
- Linux网络编程:一个简单的正向代理服务器的实现
Linux是一个可靠性非常高的操作系统,但是所有用过Linux的朋友都会感觉到, Linux和Windows这样的"傻瓜"操作系统(这里丝毫没有贬低Windows的意思,相反这应该 ...
- python高级编程 编写一个包1
#目的是:编写,发行python包可重复过程"""1:是缩短开始真正工作之前所需要的设置时间,也就是提供模板2:提供编写包的标准化方法3:简化测试驱动开发方法的使用4:为 ...
- [Python 网络编程] TCP、简单socket模拟ssh (一)
OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 网络进程访问应用层: 为应用程序进程(例如:电子邮件.文件传输和终端仿真)提供网络服务: 提供用户身份 ...
- python网络编程之最简单的单工通信
tcp_server.py from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind(('',12345)) ser ...
- Python并发编程-线程-一个简单的例子
from threading import Thread import time def func(n): #子线程完成的 time.sleep(1) print(n) #多线程示例 for i in ...
- python 网络编程(四)---UDP服务端客户端
1.服务器端 UDP服务器建立与TCP相类似,具体比较如下: 补充下,第四步:不必使用listen还有accept函数. 具体代码如下:(设置socket选项省略) import socket fro ...
- Python网络编程(4)——异步编程select & epoll
在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...
- python 网络编程要点
From http://www.zhihu.com/question/19854853 Python网络编程是一个很大的范畴,个人感觉需要掌握的点有:1. 如何使用Python来创建socket, 如 ...
随机推荐
- OSCache报错error while trying to flush writer
Struts2.3+spring3+hibernate3开发现在想在原有基础上使用 oscache提高性能,使用中发现问题例如:使用struts2标签<cache:cache time=&quo ...
- 滴滴司机:要不是Uber,我买奥迪的45万元不知何时赚回来呢!
你在专车里看风景,看风景的人在系统上看你.补贴装饰了你的出行,你装饰了平台的梦. 这是移动互联网时代城市人们每天出行的形象写照.受“份子钱”之苦的出租车司机既享受也抗议,一洗“黑车”之名的专职司机满城 ...
- 关于tableView的简单实例
关于tableCell选中颜色 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionSty ...
- SQL Server索引进阶:第四级,页和区
原文地址: Stairway to SQL Server Indexes: Level 4, Pages and Extents 本文是SQL Server索引进阶系列(Stairway to SQL ...
- js字面量
以前一直对js字面量模棱两可. '字面量是一种表示值的记法.' js字面量(literal) 分为以下几个 number literal 8 就是数字字面量 string liter ...
- 我的一个关于RFID的项目总结
去年做的一个项目,今天在这里想总结一下,这是主要流程: [0]RFID(Reader)---->[1]网络---->[2]接收处理程序---->[3]队列---->[4]读/存 ...
- JavaSE_ 面向对象 总目录(7~10)
JavaSE学习总结第07天_面向对象2 07.01 成员变量和局部变量的区别07.02 方法的形式参数是类名的调用07.03 匿名对象的概述和应用07.04 封装的概述07.05 封装的好处和设计原 ...
- jQuery学习之结构解析
jQuery内核解析 1.jQuery整体的结构是一个匿名函数 (function( window, undefined ) {})(window); 2.jQuery就是一个很普通的函数,也是一个很 ...
- InputStream和OutputStream 何时使用
原文引自:http://blog.csdn.net/fyxxq/article/details/7071978 记得刚学习程序流一章的时候,就是搞不清楚In和Out,不知道什么时候用in什么时候用ou ...
- 字节转换/编码转换全为转载GBK,BIG5,utf8,unicode
C/C++中的字节转换 宽字节转单字节 :size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count ); 单字节转宽字节 :si ...