博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python Socket,How to Create Socket Server? - 网络编程实例
阅读量:4683 次
发布时间:2019-06-09

本文共 7178 字,大约阅读时间需要 23 分钟。

文章出自:

原创译文,如有版权问题请联系删除。

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/pythonimport socket   #for socketsimport sys  #for exitHOST = ''   #HOST name or IP addressPORT = 7001             #remote ports = 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 connectings.listen(10) #why we input 10, you can read manual about listen functionprint('Socket now listening')

  Accept connection:

  方法: socket_accpect用来接收请求。  

#!/usr/bin/pythonimport socket   #for socketsimport sys  #for exitHOST = ''   #HOST name or IP addressPORT = 7001             #remote ports = socket.socket(socket.AF_INET,socket.SOCK_STREAM)print ('Socket created')#bind ip/porttry:    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 connectings.listen(10)print('Socket now listening')#wait to accept a connection - blocking callconn, addr = s.accept() #display client informationprint ('Connected with ' + addr[0] + ':' + str(addr[1]))

  结果输出:

  

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

  Receving/send Data:  

#!/usr/bin/pythonimport socket   #for socketsimport sys  #for exitHOST = ''   #HOST name or IP addressPORT = 7001             #remote ports = socket.socket(socket.AF_INET,socket.SOCK_STREAM)print ('Socket created')#bind ip/porttry:    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 connectings.listen(10)print('Socket now listening')#wait to accept a connection - blocking callconn, addr = s.accept() #display client informationprint ('Connected with ' + addr[0] + ':' + str(addr[1]))#now keep talking with the clientdata = conn.recv(1024)print(data)conn.sendall(data) #close and dispoiled socketconn.close()s.close()

  然后连接到这台server,需要注意的是如果防火墙开启,要注意设置的端口是否可以安全访问。如果答案是肯定的,你将看到:

  

  现在我们已经完成了一个绑定/监听/同意请求的一个完整连接,但是你会发现,在代码执行完成并返回'Hello'后会退出,这样的设计是效率非常低下的,实际上我们的很多逻辑是在接收完成数据后才执行的。

  在现实使用的应用场景中,我们的server需要的是 Keep running non-stop, 有一种方法就是将Accpect()方法放在循环中,这样的话它将会一直接收客户端发来的请求。  

  Live Server:

  顾名思义,一直运行(监听客户端请求并同意处理请求)。  

#!/usr/bin/pythonimport socket   #for socketsimport sys  #for exitHOST = ''   #HOST name or IP addressPORT = 7001             #remote ports = socket.socket(socket.AF_INET,socket.SOCK_STREAM)print ('Socket created')#bind ip/porttry:    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 connectings.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 clientwhile 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 socketconn.close()s.close()

  输出结果:

  server:

  

  client:

  

  到目前为止,我们做的不错,但是这个不是一个有效的网络通信实例,server端的代码在一个循环中同意client的请求并回应给他们,然后并没有针对接收到的请求的数据做任何的处理,同时它也没有能力处理同一时间的多个请求,现在我们就来处理这个问题。

  Handling Connections:

  想要处理每个请求连接,我们需要一个独立的代码处理逻辑和一台独立的服务器,有一种办法就是使用多线程,主服务器同意请求然后创建一个线程去管理这个请求,然后服务器返回在继续处理其他请求。  

#!/usr/bin/pythonimport socket   #for socketsimport sys  #for exitimport threading# from thread  import *HOST = ''   #HOST name or IP addressPORT = 7001             #remote ports = socket.socket(socket.AF_INET,socket.SOCK_STREAM)print ('Socket created')#bind ip/porttry:    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 connectings.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 threadsdef 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 clientwhile 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 socketconn.close()s.close()

  输出结果:

  server:

  

  Client:

  

  So,现在我们拥有了一个server,它是一个很棒的学你说话的机器人,HAHA

  Conclusion:

  截至目前,我相信你已经掌握了在Python中基础的socket网络编程,你可以尝试创建其他的社交客户端或与其相近的实例。至此,放学。不会再讲5分钟。

  Bug fix:

  开发环境: Python3.4 + ptvs

  以上代码均已通过测试,当然不排除Python版本不一样的情况,实际上我也在原作者的基础上修改了很多,如果有bug的话,欢迎指正。  

 

转载于:https://www.cnblogs.com/tymonyang/p/4839006.html

你可能感兴趣的文章
中国计算机学会推荐国际学术会议和期刊目录
查看>>
文本元素
查看>>
各种可以远程
查看>>
对服务器的认识
查看>>
分治法实现1-N的数字按字典序全排列组合 Java语言
查看>>
序列化 与 反序列化
查看>>
购物车
查看>>
矩阵中路径数目问题
查看>>
NSURLRequest POST方式请求服务器示例
查看>>
《精通并发与Netty》学习笔记(07 - 基于Thrift实现Java与Python的RPC调用)
查看>>
upload To upyun
查看>>
代码的组织和部署
查看>>
Leetcode 252: Meeting Rooms
查看>>
c# static 常量
查看>>
for循环:用turtle画一颗五角星
查看>>
子组件向父组件传递信息
查看>>
winform无需安装pdf阅读器打开pdf文件
查看>>
html(二) -- 文本标签和实体字符
查看>>
python基础(一)
查看>>
UI设计篇·入门篇·绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转...
查看>>