设为首页 收藏本站
查看: 768|回复: 0

[经验分享] Python Socket,How to Create Socket Server?

[复制链接]

尚未签到

发表于 2015-11-30 07:21:22 | 显示全部楼层 |阅读模式
  文章出自:Python socket – network programming tutorial by Silver Moon
  原创译文,如有版权问题请联系删除。
  Network programing in Python:
  Part2: Programing sockets servers.
  在所有的通信实例中,都分为Client 和Server. 其中:Client是请求的发起点,Server是使用Socket接收传入的值并且提供返回数据。
  Server的职能如下:
  1>.创建/打开一个socket
  2>.绑定IP地址(端口) (Bind IP with port)
  3>.监听请求的连接(Listen for incoming conecting)
  4>.同意连接(Accpect connecting)
  5>.读取/发送
  OK,到此,我们明白了server要做什么和怎么做(上面所描述的代码执行的顺序也是不能随意修改的)。在上一节点Part1中,我们已经掌握如何创建和打开一个socket,
  接下来我们就要学习如何绑定和监听。
  Bind a socket:  



#!/usr/bin/python
import socket   #for sockets
import sys  #for exit

HOST = ''   #HOST name or IP address
PORT = 7001             #remote port

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Socket created')
try:
s.bind((HOST,PORT))
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()     
print ('Socket bind complete')
  现在,利用IP地址和端口的绑定已经完成了,在绑定之前,你必须确保所有的请求方的数据能够通过这个端口被访问,接下来开始监听连接,当然不排除多个不同的程序监听同一个端口的情况。(如何处理这样的情况??!)
  Listen for incoming connections:
  成功绑定之后,要监听这个连接,方法:socket_listen用来监听,只需要在bind()成功后加上如下代码即可:  



#listen connecting
s.listen(10) #why we input 10, you can read manual about listen function
print('Socket now listening')
  Accept connection:
  方法: socket_accpect用来接收请求。  



#!/usr/bin/python
import socket   #for sockets
import sys  #for exit

HOST = ''   #HOST name or IP address
PORT = 7001             #remote port

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Socket created')
#bind ip/port
try:
s.bind((HOST,PORT))
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print ('Socket bind complete')
#listen connecting
s.listen(10)
print('Socket now listening')
#wait to accept a connection - blocking call
conn, addr = s.accept()
#display client information
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
  结果输出:

  现在程序已经开始等待请求数据从port 7001, 不要关闭程序,让它保持运行,我们看看会得到什么...
  Receving/send Data:  



#!/usr/bin/python
import socket   #for sockets
import sys  #for exit

HOST = ''   #HOST name or IP address
PORT = 7001             #remote port

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Socket created')
#bind ip/port
try:
s.bind((HOST,PORT))
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print ('Socket bind complete')
#listen connecting
s.listen(10)
print('Socket now listening')
#wait to accept a connection - blocking call
conn, addr = s.accept()
#display client information
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
#now keep talking with the client
data = conn.recv(1024)
print(data)
conn.sendall(data)
#close and dispoiled socket
conn.close()
s.close()
  然后连接到这台server,需要注意的是如果防火墙开启,要注意设置的端口是否可以安全访问。如果答案是肯定的,你将看到:

  现在我们已经完成了一个绑定/监听/同意请求的一个完整连接,但是你会发现,在代码执行完成并返回'Hello'后会退出,这样的设计是效率非常低下的,实际上我们的很多逻辑是在接收完成数据后才执行的。
  在现实使用的应用场景中,我们的server需要的是 Keep running non-stop, 有一种方法就是将Accpect()方法放在循环中,这样的话它将会一直接收客户端发来的请求。  
  Live Server:
  顾名思义,一直运行(监听客户端请求并同意处理请求)。  



#!/usr/bin/python
import socket   #for sockets
import sys  #for exit

HOST = ''   #HOST name or IP address
PORT = 7001             #remote port

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Socket created')
#bind ip/port
try:
s.bind((HOST,PORT))
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print ('Socket bind complete')
#listen connecting
s.listen(10)
print('Socket now listening')
#simple way as server
#-------------------------------------------------------
#wait to accept a connection - blocking call
#conn, addr = s.accept()
##display client information
#print ('Connected with ' + addr[0] + ':' + str(addr[1]))
##now keep talking with the client
#data = conn.recv(1024)
#-------------------------------------------------------
#liver server, always running
#-------------------------------------------------------
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))     
data = conn.recv(1024)
#reply = 'OK...' + data
if not data:
break
conn.sendall(data)
print(data)
#-------------------------------------------------------
#close and dispoiled socket
conn.close()
s.close()
  输出结果:
  server:

  client:

  到目前为止,我们做的不错,但是这个不是一个有效的网络通信实例,server端的代码在一个循环中同意client的请求并回应给他们,然后并没有针对接收到的请求的数据做任何的处理,同时它也没有能力处理同一时间的多个请求,现在我们就来处理这个问题。
  Handling Connections:
  想要处理每个请求连接,我们需要一个独立的代码处理逻辑和一台独立的服务器,有一种办法就是使用多线程,主服务器同意请求然后创建一个线程去管理这个请求,然后服务器返回在继续处理其他请求。  



#!/usr/bin/python
import socket   #for sockets
import sys  #for exit
import threading
# from thread  import *

HOST = ''   #HOST name or IP address
PORT = 7001             #remote port

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print ('Socket created')
#bind ip/port
try:
s.bind((HOST,PORT))
except socket.error as msg:
print ('Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
sys.exit()
print ('Socket bind complete')
#listen connecting
s.listen(10)
print('Socket now listening')
#simple way as server
#-------------------------------------------------------
#wait to accept a connection - blocking call
#conn, addr = s.accept()
##display client information
#print ('Connected with ' + addr[0] + ':' + str(addr[1]))
##now keep talking with the client
#data = conn.recv(1024)
#-------------------------------------------------------
#liver server, always running
#-------------------------------------------------------
#now keep talking with the client
#while 1:
#    #wait to accept a connection - blocking call
#    conn, addr = s.accept()
#    print ('Connected with ' + addr[0] + ':' + str(addr[1]))     
#    data = conn.recv(1024)
#    #reply = 'OK...' + data
#    if not data:
#        break
#    conn.sendall(data)
#    print(data)
##-------------------------------------------------------
#Function for handling connections. This will be used to create threads
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
reply = 'OK...' + data
if not data:
break
conn.sendall(reply)
#came out of loop
    conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    #start_new_thread(clientthread ,(conn,))
  threading._start_new_thread(clientthread ,(conn,))
#close and dispoiled socket
conn.close()
s.close()
  输出结果:
  server:

  Client:

  So,现在我们拥有了一个server,它是一个很棒的学你说话的机器人,HAHA
  Conclusion:
  截至目前,我相信你已经掌握了在Python中基础的socket网络编程,你可以尝试创建其他的社交客户端或与其相近的实例。至此,放学。不会再讲5分钟。
  Bug fix:
  开发环境: Python3.4 + ptvs
  以上代码均已通过测试,当然不排除Python版本不一样的情况,实际上我也在原作者的基础上修改了很多,如果有bug的话,欢迎指正。  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-145076-1-1.html 上篇帖子: Python开发入门与实战13-基于模板的界面 下篇帖子: 每个 Python 程序员都要知道的日志实践
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表