1)当您通过套接字发送消息时,您不知道它将被分成多少块。它可能会立即发送;或者可以发送前 3 个字母,然后发送其余的消息;或者消息可能被分成 10 段。
2)给定1)服务器应该如何知道它何时收到了客户端发送的所有块?例如,假设服务器接收到客户端消息的 1 块。服务器如何知道这是整个消息还是还有 9 个块即将到来?
3)我建议你读这个:
http://docs.python.org/2/howto/sockets.html
(加上评论中的链接)
4) 现在,你为什么不使用 python 创建 HTTP 服务器?
蟒蛇3:
import http.server
import socketserver
PORT = 8000
handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), handler)
print("serving at port", PORT)
httpd.serve_forever()
蟒蛇2:
import SimpleHTTPServer
import SocketServer
PORT = 8000
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), handler)
print "serving at port", PORT
httpd.serve_forever()
SimpleHTTPRequestHandler 从服务器程序的目录和下面提供文件,将请求 url 与您创建的目录结构相匹配。如果您请求“/”,服务器将在服务器所在的同一目录中提供一个 index.html 文件。这是 python 3 的客户端套接字示例(下面的 python 2 示例):
import socket
import sys
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print('Failed to create socket')
sys.exit()
print('Socket Created')
#To allow you to immediately reuse the same port after
#killing your server:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = 'localhost';
port = 8000;
s.connect((host , port))
print('Socket Connected to ' + host + ' on port ', port)
#Send some data to server
message = "GET / HTTP/1.1\r\n\r\n"
try :
#Send the whole string(sendall() handles the looping for you)
s.sendall(message.encode('utf8') )
except socket.error:
print('Send failed')
sys.exit()
print('Message sent successfully')
#Now receive data
data = []
while True:
chunk = s.recv(4096) #blocks while waiting for data
if chunk: data.append(chunk.decode("utf8"))
#If the recv() returns a blank string, then the other side
#closed the socket, and no more data will be sent:
else: break
print("".join(data))
--output:--
Socket Created
Socket Connected to localhost on port 8000
Message sent successfully
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.2.3
Date: Sat, 08 Jun 2013 09:15:18 GMT
Content-type: text/html
Content-Length: 23
Last-Modified: Sat, 08 Jun 2013 08:29:01 GMT
<div>hello world</div>
在 python 3 中,你必须使用带有套接字的字节字符串,否则你会得到可怕的:
TypeError: 'str' does not support the buffer interface
这是在 python 2.x 中:
import socket
import sys
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print('Socket Created')
#To allow you to immediately reuse the same port after
#killing your server:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = 'localhost';
port = 8000;
s.connect((host , port))
print('Socket Connected to ' + host + ' on port ', port)
#Send some data to server
message = "GET / HTTP/1.1\r\n\r\n"
try :
#Send the whole string(handles the looping for you)
s.sendall(message)
except socket.error:
print 'Send failed'
sys.exit()
print 'Message sent successfully'
#Now receive data
data = []
while True:
chunk = s.recv(4096) #blocks while waiting for data
if chunk: data.append(chunk)
#If recv() returns a blank string, then the other side
#closed the socket, and no more data will be sent:
else: break
print("".join(data))
--output:--
Message sent successfully
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.3
Date: Sat, 08 Jun 2013 10:06:04 GMT
Content-type: text/html
Content-Length: 23
Last-Modified: Sat, 08 Jun 2013 08:29:01 GMT
<div>hello world</div>
请注意,GET 请求的标头告诉服务器 HTTP 1.1 将是协议,即管理对话的规则。正如 HTTP 1.1 的 RFC 所描述的,请求中必须有两个 '\r\n' 序列。所以服务器正在寻找第二个 '\r\n' 序列。如果您从请求中删除了 '\r\n' 序列之一,客户端将挂在 recv() 上,因为服务器仍在等待更多数据,因为服务器尚未读取第二个 '\r\n'顺序。
另请注意,您将以字节形式发送数据(在 python 3 中),因此不会有任何自动 '\n' 转换,并且服务器将期待序列 '\r\n'。