未缩进
1、创建socket的服务管理程序:(唯一的目的使用来设置和管理套接字连接)server_socket.py
initialize_server方法:
def initialize_server(host, port): print "Starting server on %s:%s" % (host,port) srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Set the socket reuse to 1, so that socket terminates quicker srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: srv.bind((host, port)) except socket.error , msg: print "Bind failed. Error: " + str(msg[0]) + "\nMessage: " + msg[1] sys.exit(-1) srv.listen(1) #Currently only one client at the time return srv
2、initialize_server函数调用之后一个套接字会被绑定,函数给调用函数返回一个句柄用来操作和终止这个套接字。
还需要一个方法来等待客户端的连接,只需调用socket.accept()函数
def wait_for_client(server_socket): (client, c_address) = server_socket.accept() #blocking wait for a client print "Received a connection from [%s]" % c_address[0] return client
3、创建服务器响应类echo_sever.py 必须import sever_socket class,此类用于创建、管理、终止与客户端的通信
代码如下:#!/usr/bin/pythonimport server_socket
print "Starting echo server.." srv = server_socket.initialize_server("", 7777)
#初始化套接字 #参数 "" 而非 localhost,表示不只接受本机服务而且,而且接受来自外部的网络连接
#端口7777是任意选择的未被占用的端口,特定的协议会占用特定的端口 如FTP 协议占用21,SSH占用22,HTTP占用80 详见http://en.wikipedia.org/
#wiki/List_of_TCP_and_UDP_port_numbers ,一般的超过1023的是安全的
4、客户端处理过程
while True: print "Waiting for someone to chat with..." # This will be a blocking wait client = server_socket.wait_for_client(srv) client.send("This is an echo server. Let me know if you want to quit with 'quit' or 'exit'")
当server_socket.wait_for_client(srv)返回时,即连接到client,发送给客户机一个连接成功的消息。
之后使用另一个loop处理客户端的请求:
exit_requested = 0 #Now client has connected, and let's start our messaging loop while not exit_requested: data = client.recv(1024) # Always attempt reading 1024 bytes print "received [%s] from client" % data #check the message if "quit" in data or "exit" in data: exit_requested = 1 else: print "replying..." msg = "You wrote [%s]" % data client.sendall(msg) # Disconnect the client when we exit the while loop client.send("thanks for coming!") client.close()
##测试功能:检验client端是否要退出、如果是结束连接、如果不是将客户端发来的消息发回
##此程序recv()函数会阻塞处理器直到收到一个消息。如果有多个client连接的时候需要考虑使用非阻塞方式、和超时机制
##可以通过设置setblocking(0) 来实现非阻塞方式,通过catch exception :socket.EWOULDBOCK 、 socket.EAGAIN
##当recv()没有收到新的数据的时候 。
失败 socket 未定义