Python + ocaml TCPServer,TIME_WAIT

时间:2018-08-23 14:56:23

标签: python sockets tcp ocaml

我正在尝试让ocaml(客户端)进程通过TCP套接字与python(服务器)进程通信;它们都很简单,只需要彼此发送许多小json消息即可。但是,过了一会儿-建立了很多连接后-客户端不再能够连接;运行$ file /proc/1/cmdline /proc/1/cmdline: empty $ du -h /proc/1/cmdline 0 /proc/1/cmdline 会显示许多处于TIME_WAIT状态的连接。我的直觉是问题出在python服务器上,因为netcat一旦进入此状态也无法连接。我想知道这里是否有人可以看一下我的python服务器代码,并告诉我是否正确执行了所有操作?我包括ocaml服务器以确保完整性。

这是一个最小的工作示例:客户端和服务器应该无限期地交换ping / pong。

netstat

ocaml客户端:

import socketserver
import json
import codecs
import socket

class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass


class CommandHandler(socketserver.StreamRequestHandler):
    def handle(self):
        k = json.load(codecs.getreader('utf-8')(self.rfile))
        assert k == "ping"
        self.wfile.write(bytes(json.dumps("pong"), 'ascii'))
        self.request.shutdown(socket.SHUT_RDWR)
        self.request.close()

socketserver.TCPServer.allow_reuse_address = True
server = ThreadedTCPServer(("localhost", 9119), CommandHandler, False)
server.allow_reuse_address = True
server.server_bind()
server.server_activate()


server.serve_forever()

就其价值而言,我有许多客户端同时运行,因此服务器一次要建立大量的连接,持续几个小时。这是客户端最终输出的内容:

open Core

let send_to_server message =
  let open Yojson.Safe in
  let p = 9119 in
  let h = Unix.Inet_addr.localhost in
  let (ic,oc) = Unix.open_connection (ADDR_INET(h,p)) in
  Yojson.Safe.to_channel oc message;
  Out_channel.flush oc;
  Unix.shutdown ~mode:SHUTDOWN_SEND (Unix.descr_of_out_channel oc);

  let r = Yojson.Safe.from_channel ic in
  Unix.shutdown ~mode:SHUTDOWN_RECEIVE (Unix.descr_of_in_channel ic);
  In_channel.close ic;

  r

let rec stress_test_client countdown =
  let open Yojson.Basic.Util in
  let m = (`String("ping")) in
  assert(send_to_server m = `String("pong"));
  if countdown = 0 then
  (Printf.printf "+";
  Pervasives.flush stdout);
  stress_test_client (if countdown = 0 then 1000 else countdown - 1)
;;


stress_test_client 1000;;

几分钟后,这里是 (Unix.Unix_error "Cannot assign requested address" connect "((addr (ADDR_INET 127.0.0.1 9119)))") 的输出:

netstat

...但是,反复与netcat连接似乎可行,因此该错误可能在客户端中:

$ netstat|grep -F 'localhost:9119'|head
tcp        0      0 localhost:51462         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:43853         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:43380         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:57290         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:45057         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:47191         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:37802         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:55206         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:46369         localhost:9119          TIME_WAIT  
tcp        0      0 localhost:55730         localhost:9119          TIME_WAIT

没有出现任何明显的问题。

0 个答案:

没有答案