今天将python中socket模块的基本API学习完后,照着书上的实例编写一个套接字服务器和客户端。采用python3.5版本,在注释中会标明python2和python3的不同之处。

1.代码

(1)服务器端及对应代码解释

  1. # ! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # 编写回显服务器
  4.  
  5. import socket
  6. import sys
  7. import argparse
  8.  
  9. # 定义常量
  10. host = 'localhost'
  11. data_payload = 2048
  12. backlog = 5
  13.  
  14. def echo_server(port):
  15.  
  16. # 创建一个TCP socket
  17. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  18.  
  19. # 设置TCP套接字关联选项——重用地址
  20. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  21.  
  22. # 建立套接字端口
  23. server_address = (host, port)
  24. print("Starting up echo server on %s port %s" % server_address)
  25.  
  26. # 将socket绑定到server_address地址
  27. sock.bind(server_address)
  28.  
  29. # 监听客户端
  30. # backlog指定最多允许多少个客户连接到服务器。它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
  31. # 这里设定为5
  32. sock.listen(backlog)
  33. # 在调用 Listen 之前,必须首先调用 Bind 方法,否则 Listen 将引发 SocketException。
  34. while True:
  35. print("Waiting to receive message from client")
  36.  
  37. # 调用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。
  38. # accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection
  39. # 是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
  40. client, address = sock.accept()
  41.  
  42. # 指定data最大长度为2048字节
  43. data = client.recv(data_payload)
  44. if data:
  45. print("Data: %s" % data)
  46. client.send(data)
  47. print("sent %s bytes back to %s" % (data, address))
  48. # 关闭连接
  49. client.close()
  50.  
  51. if __name__ == '__main__':
  52. # 创建一个解析对象,其中描述为"Socket Error Examples"
  53. parser = argparse.ArgumentParser(description='Socket Server Example')
  54. # 采用add_argument方法
  55. # name or flags —— 必须的参数,该参数接收选项参数或者是位置参数
  56. # action:
  57. # (1)store —— 默认action模式,储存值到指定变量
  58. # (2)store_const —— 储存值在参数的const部分指定,多用于实现非布尔的命令行flag
  59. # (3)store_true/store_false —— 布尔开关。可以2个参数对应一个变量
  60. # (4)append —— 储存值到列表,储存值在参数的const部分指定
  61. # (5)append_const —— 储存值到列表,储存值在参数的const部分指定
  62. # (6)version —— 输出版本信息然后退出
  63. # type —— 把从命名行输入的结果转成设置的类型,通常用来检查值的范围,以及合法性。默认string  
  64. # required —— 指定某个选项在命名中出现, 默认False, 若为 True, 表示必须输入该参数
  65. # dest —— 把位置或者选项关联到一个特定的名字
  66. parser.add_argument('--port', action="store", dest="port", type=int, required=True)
  67. # 调用parse_args()方法进行解析
  68. given_args = parser.parse_args()
  69. port = given_args.port
  70. echo_server(port)
  71.  
  72. def bind(self, address): # real signature unknown; restored from __doc__
  73. """
  74. bind(address)
  75.  
  76. Bind the socket to a local address. For IP sockets, the address is a
  77. pair (host, port); the host must refer to the local host. For raw packet
  78. sockets the address is a tuple (ifname, proto [,pkttype [,hatype]])
  79. """
  80. pass
  81. def listen(self, backlog=None): # real signature unknown; restored from __doc__
  82. """
  83. listen([backlog])
  84.  
  85. Enable a server to accept connections. If backlog is specified, it must be
  86. at least 0 (if it is lower, it is set to 0); it specifies the number of
  87. unaccepted connections that the system will allow before refusing new
  88. connections. If not specified, a default reasonable value is chosen.
  89. """
  90. pass

服务器端代码

(2)客户端及对应代码解释

  1. # ! /usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # 编写回显客户端
  4.  
  5. import socket
  6. import sys
  7. import argparse
  8.  
  9. host = 'localhost'
  10.  
  11. def echo_client(port):
  12. # 创建TCP socket连接
  13. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  14. # 获取服务器端host和端口号
  15. server_address = (host, port)
  16. print("Connecting to %s port %s" % server_address)
  17. sock.connect(server_address)
  18.  
  19. try:
  20. # 将message内容发送到服务器端
  21. message = "Test message, This will be echoed"
  22. print("Sending %s" % message)
  23. # python2和python3此处不同
  24. # python2—— sock.sendall(message)
  25. # sendall()发送完整的TCP数据,成功返回None,失败抛出异常
  26. sock.sendall(message.encode())
  27.  
  28. # 服务器端将发送的数据回传给客户端并打印
  29. amount_received = 0
  30. amount_expected = len(message)
  31. while amount_received < amount_expected:
  32. data = sock.recv(1024)
  33. amount_received += len(data)
  34. print("Received: %s" % data)
  35. # 处理相对应错误
  36. except socket.error as e:
  37. print("socket error: %s" % str(e))
  38. except Exception as e:
  39. print("Other exception: %s" % str(e))
  40. finally:
  41. print("Closing connection to the server")
  42. sock.close()
  43.  
  44. if __name__ == '__main__':
  45. parser = argparse.ArgumentParser(description='Socket Server Example')
  46. parser.add_argument('--port', action="store", dest="port", type=int, required=True)
  47. given_args = parser.parse_args()
  48. port = given_args.port
  49. echo_client(port)

客户端代码

(3)运行结果

  1. 1. 服务器端
  2. Abel$ python3 1_13a_echo_server.py --port=9900
  3. Starting up echo server on localhost port 9900
  4. Waiting to receive message from client
  5.  
  6. 2.客户端发送数据时,服务器端
  7. Data: b'Test message, This will be echoed'
  8. sent b'Test message, This will be echoed' bytes back to ('127.0.0.1', 62389)
  9. Waiting to receive message from client
  10.  
  11. 3.客户端
  12. Abel$ python3 1_13b_echo_client.py --port=9900
  13. Connecting to localhost port 9900
  14. Sending Test message, This will be echoed
  15. Received: b'Test message, This will be echoed'
  16. Closing connection to the server

Python网络编程——编写一个简单的回显客户端/服务器应用的更多相关文章

  1. python2.7_1.14_编写一个简单的回显客户端/服务器应用

    1.服务端 server.py # -*- coding: utf-8 -*- import socket import argparse host = 'localhost' data_payloa ...

  2. Linux网络编程:一个简单的正向代理服务器的实现

    Linux是一个可靠性非常高的操作系统,但是所有用过Linux的朋友都会感觉到, Linux和Windows这样的"傻瓜"操作系统(这里丝毫没有贬低Windows的意思,相反这应该 ...

  3. python高级编程 编写一个包1

    #目的是:编写,发行python包可重复过程"""1:是缩短开始真正工作之前所需要的设置时间,也就是提供模板2:提供编写包的标准化方法3:简化测试驱动开发方法的使用4:为 ...

  4. [Python 网络编程] TCP、简单socket模拟ssh (一)

    OSI七层模型(Open System Interconnection,开放式系统互联) 应用层 网络进程访问应用层: 为应用程序进程(例如:电子邮件.文件传输和终端仿真)提供网络服务: 提供用户身份 ...

  5. python网络编程之最简单的单工通信

    tcp_server.py from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind(('',12345)) ser ...

  6. Python并发编程-线程-一个简单的例子

    from threading import Thread import time def func(n): #子线程完成的 time.sleep(1) print(n) #多线程示例 for i in ...

  7. python 网络编程(四)---UDP服务端客户端

    1.服务器端 UDP服务器建立与TCP相类似,具体比较如下: 补充下,第四步:不必使用listen还有accept函数. 具体代码如下:(设置socket选项省略) import socket fro ...

  8. Python网络编程(4)——异步编程select & epoll

    在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...

  9. python 网络编程要点

    From http://www.zhihu.com/question/19854853 Python网络编程是一个很大的范畴,个人感觉需要掌握的点有:1. 如何使用Python来创建socket, 如 ...

随机推荐

  1. OSCache报错error while trying to flush writer

    Struts2.3+spring3+hibernate3开发现在想在原有基础上使用 oscache提高性能,使用中发现问题例如:使用struts2标签<cache:cache time=&quo ...

  2. 滴滴司机:要不是Uber,我买奥迪的45万元不知何时赚回来呢!

    你在专车里看风景,看风景的人在系统上看你.补贴装饰了你的出行,你装饰了平台的梦. 这是移动互联网时代城市人们每天出行的形象写照.受“份子钱”之苦的出租车司机既享受也抗议,一洗“黑车”之名的专职司机满城 ...

  3. 关于tableView的简单实例

    关于tableCell选中颜色 //无色 cell.selectionStyle = UITableViewCellSelectionStyleNone; //蓝色 cell.selectionSty ...

  4. SQL Server索引进阶:第四级,页和区

    原文地址: Stairway to SQL Server Indexes: Level 4, Pages and Extents 本文是SQL Server索引进阶系列(Stairway to SQL ...

  5. js字面量

    以前一直对js字面量模棱两可. '字面量是一种表示值的记法.' js字面量(literal) 分为以下几个 number literal        8   就是数字字面量 string liter ...

  6. 我的一个关于RFID的项目总结

    去年做的一个项目,今天在这里想总结一下,这是主要流程: [0]RFID(Reader)---->[1]网络---->[2]接收处理程序---->[3]队列---->[4]读/存 ...

  7. JavaSE_ 面向对象 总目录(7~10)

    JavaSE学习总结第07天_面向对象2 07.01 成员变量和局部变量的区别07.02 方法的形式参数是类名的调用07.03 匿名对象的概述和应用07.04 封装的概述07.05 封装的好处和设计原 ...

  8. jQuery学习之结构解析

    jQuery内核解析 1.jQuery整体的结构是一个匿名函数 (function( window, undefined ) {})(window); 2.jQuery就是一个很普通的函数,也是一个很 ...

  9. InputStream和OutputStream 何时使用

    原文引自:http://blog.csdn.net/fyxxq/article/details/7071978 记得刚学习程序流一章的时候,就是搞不清楚In和Out,不知道什么时候用in什么时候用ou ...

  10. 字节转换/编码转换全为转载GBK,BIG5,utf8,unicode

    C/C++中的字节转换 宽字节转单字节 :size_t wcstombs( char *mbstr, const wchar_t *wcstr, size_t count ); 单字节转宽字节 :si ...