Java服务器套接字通信非常慢

时间:2012-04-18 18:49:15

标签: java python sockets

Linux上的本地。 20k消息大约需要10秒钟。我的猜测是我的Java很糟糕而且Python很好。

py客户端:

def scan(self, msg):
    try:
        print 'begin scan'
        HOST = 'localhost'
        PORT = 33000
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((HOST, PORT));
        s.sendall(msg)
        data = s.recv(1024)
        s.close()
        print 'Received', repr(data)
    except Exception, e:
        print "error: " + str(e)

Java服务器:

    ServerSocket service = new ServerSocket(33000); 

    while(true) {

    debug("Begin waiting for connection");

    //this spins
    Socket connection = service.accept();

    debug("Connection received from " + connection.getInetAddress().getHostName());

    OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
    BufferedInputStream in = new BufferedInputStream(connection.getInputStream());


    ScanResultsHeader results = new ScanResultsHeader();

        Scanner scanner = new Scanner();
        results = scanner.scan("scannerfake@gmail.com", "123", in);

public Sc​​anResultsHeader scan(String userEmail,                    字符串imapRetrievalId,                    BufferedInputStream mimeEmail)     抛出IOException,FileNotFoundException,MimeException,ScannerException {

    //how fast would it be to just slurp up stream?
    debug("slurp!");
    String slurp = IOUtils.toString(mimeEmail);
    debug("slurped " + slurp.length() + " characters");
    slurp = slurp.toLowerCase();
    debug("lc'ed it");
    //...

我的猜测是我错误地处理输入流。一个问题是库API扫描正在使用“BufferedInputStream mimeEmail”签名,因此我最终需要访问该表单。但是我注意到一个简单的sl sl string takes takes takes takes takes takes takes takes takes takes so so so so so so so so so so

2 个答案:

答案 0 :(得分:0)

修改我的答案......

如果您正在高效阅读,而且看起来很有效,那么只会花费很多时间,因为

  • 每次发送可能非常昂贵的邮件时,您都在创建新连接。
  • 您没有像您想象的那样快速地发送数据。
  • 消息非常大(不太可能,但可能是)

有很多关于如何做到这一点的例子,你可以使用的一个好的库是IOUtils,这使得它更简单。

您应该能够通过Java在单个套接字上发送大约200K / s的消息。


如果您使用Big Endian发送X字节协议,则可以执行此操作。

DataInputStream dis = new DataInputStream( ...
int len = dis.readInt();
byte[] bytes = new byte[len];
dis.readFully(bytes);
String text = new String(bytes, "UTF-8");

答案 1 :(得分:0)

原始问题是客户端没有发送输入结束,因此“slurp”操作一直在等待更多东西通过连接。

解决方案是实现应用层协议以提前发送消息的大小,然后在那么多字节之后停止侦听更多消息。我更喜欢标准库 - 类似于,FiniteInputStream扩展BufferedInputStream并将大小作为参数,但我自己写了。