123
返回列表 发新帖
楼主: jieforest

Python网络Socket编程

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
21#
 楼主| 发表于 2012-11-4 14:12 | 只看该作者
一直在运行的服务器

对上述代码稍作改动:
  1. import socket
  2. import sys

  3. HOST = ''        # Symbolic name meaning all available interfaces
  4. PORT = 8888        # Arbitrary non-privileged port

  5. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  6. print 'Socket created'

  7. try:
  8.         s.bind((HOST, PORT))
  9. except socket.error , msg:
  10.         print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
  11.         sys.exit()
  12.        
  13. print 'Socket bind complete'

  14. s.listen(10)
  15. print 'Socket now listening'

  16. #now keep talking with the client
  17. while 1:
  18.     #wait to accept a connection - blocking call
  19.         conn, addr = s.accept()
  20.         print 'Connected with ' + addr[0] + ':' + str(addr[1])
  21.        
  22.         data = conn.recv(1024)
  23.         reply = 'OK...' + data
  24.         if not data:
  25.                 break
  26.        
  27.         conn.sendall(reply)

  28. conn.close()
  29. s.close()
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
22#
 楼主| 发表于 2012-11-4 14:13 | 只看该作者
很简单只是加多一个 while 1 语句而已。

继续运行服务器,然后打开另外三个命令行窗口。每个窗口都使用 telnet 命令连接到服务器:
  1. $ telnet localhost 5000
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. happy
  6. OK .. happy
  7. Connection closed by foreign host.
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
23#
 楼主| 发表于 2012-11-4 14:13 | 只看该作者
服务器所在的终端窗口显示的是:
  1. $ python server.py
  2. Socket created
  3. Socket bind complete
  4. Socket now listening
  5. Connected with 127.0.0.1:60225
  6. Connected with 127.0.0.1:60237
  7. Connected with 127.0.0.1:60239
复制代码
你看服务器再也不退出了,好吧,用 Ctrl+C 关闭服务器,所有的 telnet 终端将会显示 "Connection closed by foreign host."

已经很不错了,但是这样的通讯效率太低了,服务器程序使用循环来接受连接并发送回应,这相当于是一次最多处理一个客户端的请求,而我们要求服务器可同时处理多个请求。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
24#
 楼主| 发表于 2012-11-5 14:15 | 只看该作者
处理多个连接

为了处理多个连接,我们需要一个独立的处理代码在主服务器接收到连接时运行。一种方法是使用线程,服务器接收到连接然后创建一个线程来处理连接收发数据,然后主服务器程序返回去接收新的连接。

下面是我们使用线程来处理连接请求:
  1. import socket
  2. import sys
  3. from thread import *

  4. HOST = ''        # Symbolic name meaning all available interfaces
  5. PORT = 8888        # Arbitrary non-privileged port

  6. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  7. print 'Socket created'

  8. #Bind socket to local host and port
  9. try:
  10.         s.bind((HOST, PORT))
  11. except socket.error , msg:
  12.         print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
  13.         sys.exit()
  14.        
  15. print 'Socket bind complete'

  16. #Start listening on socket
  17. s.listen(10)
  18. print 'Socket now listening'

  19. #Function for handling connections. This will be used to create threads
  20. def clientthread(conn):
  21.         #Sending message to connected client
  22.         conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
  23.        
  24.         #infinite loop so that function do not terminate and thread do not end.
  25.         while True:
  26.                
  27.                 #Receiving from client
  28.                 data = conn.recv(1024)
  29.                 reply = 'OK...' + data
  30.                 if not data:
  31.                         break
  32.        
  33.                 conn.sendall(reply)
  34.        
  35.         #came out of loop
  36.         conn.close()

  37. #now keep talking with the client
  38. while 1:
  39.     #wait to accept a connection - blocking call
  40.         conn, addr = s.accept()
  41.         print 'Connected with ' + addr[0] + ':' + str(addr[1])
  42.        
  43.         #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
  44.         start_new_thread(clientthread ,(conn,))

  45. s.close()
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
25#
 楼主| 发表于 2012-11-5 14:15 | 只看该作者
运行上述服务端程序,然后像之前一样打开三个终端窗口并执行 telent 命令:
  1. $ telnet localhost 8888
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. Welcome to the server. Type something and hit enter
  6. hi
  7. OK...hi
  8. asd
  9. OK...asd
  10. cv
  11. OK...cv
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
26#
 楼主| 发表于 2012-11-5 14:16 | 只看该作者
服务器端所在终端窗口输出信息如下:
  1. $ python server.py
  2. Socket created
  3. Socket bind complete
  4. Socket now listening
  5. Connected with 127.0.0.1:60730
  6. Connected with 127.0.0.1:60731
复制代码
线程接管了连接并返回相应数据给客户端。

这便是我们所要介绍的服务器端编程。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
27#
 楼主| 发表于 2012-11-5 14:16 | 只看该作者
结论

到这里为止,你已经学习了 Python 的 Socket 基本编程,你可自己动手编写一些例子来强化这些知识。

你可能会遇见一些问题:Bind failed. Error Code : 98 Message Address already in use,碰见这种问题只需要简单更改服务器端口即可。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
28#
 楼主| 发表于 2012-11-5 14:16 | 只看该作者
over.

使用道具 举报

回复
论坛徽章:
27
开发板块每日发贴之星
日期:2008-01-17 01:06:29ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04紫蛋头
日期:2013-06-07 17:04:33马上有房
日期:2014-02-18 16:42:02懒羊羊
日期:2015-03-04 14:52:11秀才
日期:2015-08-24 09:51:48秀才
日期:2015-09-17 09:11:05天蝎座
日期:2016-01-04 11:15:24迷宫蛋
日期:2016-02-03 16:13:47咸鸭蛋
日期:2016-02-03 16:14:11
29#
发表于 2012-11-21 22:28 | 只看该作者
up,where is the function which called start_new_thread?

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表