#display client information
print 'Connected with ' + addr[0] + ':' + str(addr[1]) #now keep talking with the client data = conn.recv(1024) conn.sendall(data) conn.close() s.close()
继续运行上述代码,然后打开另外一个命令行窗口输入下面命令:
$ telnet localhost 8888 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. happy
happy
Connection closed by foreign host.
可看到客户端接收到来自服务器端的回应内容。
上面的例子还是一样,服务器端回应后就立即退出了。而一些真正的服务器像 www.oschina.net 是一直在运行的,时刻接受连接请求。
也就是说服务器端应该一直处于运行状态,否则就不能成为“服务”,因此我们要让服务器端一直运行,最简单的方法就是把 accept 方法放在一个循环内。
一直在运行的服务器 对上述代码稍作改动: #!/usr/bin/env python import socket import sys
HOST = '' # Symbolic name meaning all available interfaces PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Socket created' try:
s.bind((HOST, PORT)) except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit() print 'Socket bind complete' s.listen(10)
print 'Socket now listening'
#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(reply) conn.close() s.close()
很简单只是加多一个 while 1 语句而已。
继续运行服务器,然后打开另外三个命令行窗口。每个窗口都使用 telnet 命令连接到服务器:
$ telnet localhost 5000 Trying 127.0.0.1...
Connected to localhost. Escape character is '^]'. happy
OK .. happy
Connection closed by foreign host.
服务器所在的终端窗口显示的是:
$ python server.py Socket created
Socket bind complete Socket now listening
Connected with 127.0.0.1:60225 Connected with 127.0.0.1:60237 Connected with 127.0.0.1:60239
你看服务器再也不退出了,好吧,用 Ctrl+C 关闭服务器,所有的 telnet 终端将会显示 \
已经很不错了,但是这样的通讯效率太低了,服务器程序使用循环来接受连接并发送回应,这相当于是一次最多处理一个客户端的请求,而我们要求服务器可同时处理多个请求。
处理多个连接
为了处理多个连接,我们需要一个独立的处理代码在主服务器接收到连接时运行。一种方法是使用线程,服务器接收到连接然后创建一个线程来处理连接收发数据,然后主服务器程序返回去接收新的连接。
下面是我们使用线程来处理连接请求: #!/usr/bin/env python import socket import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Socket created'
#Bind socket to local host and port try:
s.bind((HOST, PORT)) except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit()
print 'Socket bind complete' #Start listening on socket s.listen(10)
print 'Socket now listening'
#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,)) s.close()
运行上述服务端程序,然后像之前一样打开三个终端窗口并执行 telent 命令:
$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost. Escape character is '^]'.
Welcome to the server. Type something and hit enter hi OK...hi asd OK...asd cv OK...cv
服务器端所在终端窗口输出信息如下: $ python server.py Socket created Socket bind complete Socket now listening
Connected with 127.0.0.1:60730 Connected with 127.0.0.1:60731
线程接管了连接并返回相应数据给客户端。 这便是我们所要介绍的服务器端编程。
可能会遇见一些问题:Bind failed. Error Code : 98 Message Address already in use,碰见这种问题只需要简单更改服务器端口即可。
进一步深入:客户端程序(scoketcli.py)着行去读send.txt文件发送给服务端程序(socketser.py),服务端程序读入后写入receive.txt
Socketcli.py代码如下:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #!/usr/bin/python
import socket # for sockets import sys # for exit
try: #create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1] sys.exit();
print 'Socket Created' host = '10.1.22.11' port = 8888
try: remote_ip = socket.gethostbyname( host ) except socket.gaierror:
相关推荐: