标签:
文章出自: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的话,欢迎指正。
Python Socket,How to Create Socket Server? - 网络编程实例
标签:
原文地址:http://www.cnblogs.com/yang-csharp/p/4839006.html