【问题标题】:Twisted python server and Java chatTwisted python 服务器和 Java 聊天
【发布时间】:2012-10-27 13:50:50
【问题描述】:

我在 raywenderlich.com 上找到了这个很棒的教程:

http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server

它创建了一个 Twisted Python 服务器,并与应用程序 iphone 聊天交谈,我会让服务器也与 Java 聊天交谈,现在我编写了一些代码,这是 python 服务器:

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor


class IphoneChat(Protocol):
def connectionMade(self):
    #self.transport.write("""connected""")
    self.factory.clients.append(self)
    print "clients are ", self.factory.clients

def connectionLost(self, reason):
    self.factory.clients.remove(self)

def dataReceived(self, data):
    #print "data is ", data
    a = data.split(':')
    if len(a) > 1:
        command = a[0]
        content = a[1]

        msg = ""
        if command == "iam":
            self.name = content
            msg = self.name + " has joined"

        elif command == "msg":
            msg = self.name + ": " + content

        print msg

        for c in self.factory.clients:
            c.message(msg)

def message(self, message):
    self.transport.write(message + '\n')


factory = Factory()
factory.protocol = IphoneChat
factory.clients = []

reactor.listenTCP(1025, factory)
print "Chat server started"
reactor.run()

然后我创建一个简单的 java 示例来连接到服务器:

import java.net.*;
import java.io.*;
import java.util.*;

public class MyClassSocket  {

private ObjectInputStream sInput;       // to read from the socket
private ObjectOutputStream sOutput;     // to write on the socket
private Socket socket;

private String server, username;
private int port;

MyClassSocket(String server, int port, String username) {
    this.server = server;
    this.port = port;
    this.username = username;
}

private void display(String msg) {

    System.out.println(msg);      // println in console mode

}

public boolean start() {

    try {
        socket = new Socket(server, port);
    }
    // if it failed not much I can so
    catch(Exception ec) {
        display("Error connectiong to server:" + ec);
        return false;
    }

    String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
    display(msg);

    try
    {

        sInput  = new ObjectInputStream(socket.getInputStream()); //<-------- block here
        sOutput = new ObjectOutputStream(socket.getOutputStream());
    }
    catch (IOException eIO) {
        display("Exception creating new Input/output Streams: " + eIO);
        return false;
    }

    return true;

}

public static void main(String[] args) {

    MyClassSocket client = new MyClassSocket("localhost",1025,"PieroJava");
    client.start();
}

}

代码冻结在我在上面的代码中注释的点,我可以在服务器终端看到有一个新的连接,我可以在客户端看到我连接但这里不要过去:

sInput  = new ObjectInputStream(socket.getInputStream());

我该怎么办?

【问题讨论】:

  • 你怎么知道那是客户端阻止的行?
  • 我在该行之前和之后放置了一些 System.out.println,并且只打印第一个...
  • 异常情况呢?您确定会报告异常吗?从docs.oracle.com/javase/1.4.2/docs/api/java/net/… 看来,getInputStream 不会因为任何原因而阻塞,所以你观察到它阻塞是很奇怪的。
  • 问题是我没有例外,一直卡在那里不要过去,我发现了这个类似的问题:stackoverflow.com/questions/8377291/… 这似乎是我同样的问题,在评论答案中,用户谈话发现他的问题,但他有一个java服务器......
  • 啊。该问题讨论了从输入流中读取的 ObjectInputStream 构造函数。但是您的服务器在设置时不会向连接写入任何内容。所以客户端没有什么可以读取的,所以读取会永远阻塞。

标签: java python client-server twisted


【解决方案1】:

我建议不要使用 ObjectInputStream 和 ObjectOutputStream。无论如何,让它们与 Python 服务器很好地交互可能会很有挑战性,而且它们无论如何都没有实现一个很好的协议。我推荐一个更简单的协议,具有更好的跨语言支持,例如AMP

在任何情况下,new ObjectInputStream 似乎都应该阻塞,直到它可以从连接中读取字节。如果您想让它成功,您的基于 Twisted 的服务器将需要将 Java 对象流的开头写入连接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    相关资源
    最近更新 更多