我是JavaScript和AJAX的新手。一般来说也是网络通信的新手。
我正在尝试创建一个与Python服务器通信的动态更新网页。我一直在本地测试一切,到目前为止所有的工作......我想。
Python服务器在localhost端口8000上提供“page.html”.HTML页面使用AJAX和XMLHttpRequest将数据POST到服务器。我可以很好地将数据发送到服务器。
问题在于:我的服务器指示每个帖子都会打开一个新的客户端端口。这让我感到害怕,因为我已经习惯了在单个端口上进行通信的TCP套接字。
这是服务器代码(server.py):
import cgi
import http.server
import urllib
import socketserver
class ServerHandler(http.server.SimpleHTTPRequestHandler):
def do_POST(self):
ctype, pdict = cgi.parse_header(self.headers['content-type'])
length = int(self.headers['content-length'])
postvars = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8'))
ip, port = self.client_address
print(ip, "@", port, "-->", postvars)
def start_server():
httpServer = socketserver.TCPServer(("", 8000), ServerHandler)
httpServer.serve_forever()
if __name__ == "__main__":
start_server()
这是HTML代码(page.html):
<html>
<head></head>
<body>
<script type="text/javascript">
function send_receive() {
var http = new XMLHttpRequest();
var data = document.test_form.data.value;
var params = "data=" + data.toString();
http.open("POST", "page.html", true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.send(params);
}
</script>
<form name=test_form>
Data: <input type="text" name="data" value="1">
<input type=button onClick="send_receive();" value="Send"><br /><br />
</form>
</body>
</html>
这是在页面上发送1到6后的服务器输出。
127.0.0.1 @ 52884 --> {'data': ['1']}
127.0.0.1 @ 52885 --> {'data': ['2']}
127.0.0.1 @ 52886 --> {'data': ['3']}
127.0.0.1 @ 52887 --> {'data': ['4']}
127.0.0.1 @ 52888 --> {'data': ['5']}
127.0.0.1 @ 52889 --> {'data': ['6']}
要测试启动server.py,请转到浏览器并输入
http://localhost:8000/page.html OR http://127.0.0.1:8000/page.html
正如您可以看到每个POST的端口增量。有什么我做错了吗?我觉得XHR是挥之不去的,需要关闭,但从我在网上看到的,显然每个POST都需要创建一个新的XHR。谢谢!
答案 0 :(得分:1)
没关系。 服务器从其可用池中为这些端口选择一个新的源端口 - 这确保了每个请求的HTTP的唯一 TCP connection tuple以及它建立的相应TCP连接。 (服务器选择它用于传入连接的源端口。)
无法保证将使用相同的客户端端口 - 实际上相同的源端口不能用于相同的源IP,除非TCP连接已被全封闭;这包括TIME_WAIT 1 中的那些。当TCP连接完全关闭时,源端口将被释放回可用池。
不同的源端口不表示存在问题;并且增加的值仅仅是实现(和可用池)细节。另一方面,从未关闭的连接可能是个问题。使用netstat
命令查看TCP连接及其状态。
1 在过多快速创建来自同一远程IP的连接的系统上,可能需要启用'port reuse'。
"Coping with the TCP TIME-WAIT state on busy Linux servers"文章读得很好;它包括漂亮的图表,良好的解释和对实际限制的讨论。
答案 1 :(得分:0)
嗯,我相信你没有做错任何事。 只是你误解了self.client_address中的值
self.client_address中的端口不是服务器上的端口,而是用户计算机上用于与Web服务器通信的端口。
此外,您可以在此处查看有关该端口的一些有用信息: (请检查标记为[正确答案]的答案)
How do multiple clients connect simultaneously to one port, say 80, on a server?