0

更新:完全なコード例:サーバー:

ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());
writer_.writeObject("This should be a solstice message normally.");
writer_.flush();

クライアント:

Socket clientSocket = new Socket(InetAddress.getLocalHost(), 8888);
ObjectInputStream reader = new ObjectInputStream(clientSocket.getInputStream());
Object obj = reader.readObject();
if (obj instanceof SolsticeMessage)
{
    SolsticeMessage message = (SolsticeMessage) obj;
    processMessage(message);
}
else
    System.out.println("Received a message of unknown type: " + obj.getClass());

コードを実行すると、クライアントはサーバーに接続しますが、「else」ブランチにSystem.out.println()を出力することはありません。さらに、サーバーを次のように変更した場合:

ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());
writer_.writeObject(message); // of type SolsticeMessage
writer_.flush();

適切なメッセージを書き込むために、サーバーは壊れたパイプの例外をすぐにスローします。

元の質問:クライアントが接続されるのを待つ単純なサーバーを次のように作成しようとしています。

ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());

次に、writer_がnullでないことを確認して、次の2つのメッセージをクライアントに書き込もうとします。

writer_.writeObject("This is a string.");
writer_.writeObject(message); // where message implements Serializable
writer_.flush();

クライアントコードは次のとおりです。

Socket clientSocket = new Socket(InetAddress.getLocalHost(), 8888);
ObjectInputStream reader = new ObjectInputStream(clientSocket.getInputStream());
Object obj = null;
while ((obj = reader.readObject()) != null)
{
    SolsticeMessage message = (SolsticeMessage) obj;
    processMessage(message);
}

私の予想に反して(両方のオブジェクトを書き込む必要があります)、最初のオブジェクト(String)は正常に送信されますが、2番目のオブジェクト(message)は次の例外をスローします。

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1257)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1211)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1395)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:333)
at com.kivancmuslu.www.solstice.server.SolsticeServer.sendMessage(SolsticeServer.java:146)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceChange(ResourceChangeListener.java:94)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:65)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.resourceChanged(ResourceChangeListener.java:31)
at org.eclipse.core.internal.events.NotificationManager$1.run(NotificationManager.java:291)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.NotificationManager.notify(NotificationManager.java:285)
at org.eclipse.core.internal.events.NotificationManager.broadcastChanges(NotificationManager.java:149)
at org.eclipse.core.internal.resources.Workspace.broadcastPostChange(Workspace.java:395)
at org.eclipse.core.internal.resources.Workspace.endOperation(Workspace.java:1530)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:156)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)

文字列オブジェクトが問題なく書き込まれ、ネットワーク経由で送信される理由はありますが、他のシリアル化されたオブジェクトがこの例外を引き起こしますか?また、役立つ場合に備えて、Serializedクラスを以下に添付します。

package com.kivancmuslu.www.solstice.logic;

public class ResourceChangedMessage extends SolsticeMessage
{
    /**
     * 
     */
    private static final long serialVersionUID = -2877650023886033398L;

    public static enum ResourceChangeType
    {
        ADDED, REMOVED
    }

    private final String projectName_;
    private final String relativeResourcePath_;
    private final ResourceChangeType resourceChangeType_;

    public ResourceChangedMessage(String projectName, String relativeResourcePath,
                                  ResourceChangeType resourceChangeType)
    {
        projectName_ = projectName;
        relativeResourcePath_ = relativeResourcePath;
        resourceChangeType_ = resourceChangeType;
    }

    public String getProjectName()
    {
        return projectName_;
    }

    public String getRelativeResourcePath()
    {
        return relativeResourcePath_;
    }

    public ResourceChangeType getResourceChangeType()
    {
        return resourceChangeType_;
    }
}

ここで、SolsticeMessageは次のように定義されます。

package com.kivancmuslu.www.solstice.logic;

import java.io.Serializable;

public abstract class SolsticeMessage implements Serializable
{
    private static final long serialVersionUID = 4048501241385740686L;

    public abstract String toString();
}

ありがとうございました、

4

1 に答える 1

1

接続のもう一方の端が接続を閉じているのではないかと強く思います。たとえば、次のコードを持つ別のJavaプログラムの場合:

Socket client = serverSocket.accept();
reader_ = new ObjectInputStream(client.getInputStream());
reader_.readObject();
reader_.close();

...すると、送信コードが2番目のオブジェクトを送信する場所がなくなります。残念ながら、リッスンしているコードを提供してくれません。上記は私の最善の推測です。

編集:サーバーコードを投稿したので、実際の問題を確認できます。これが読み込もうとしているものです:

while ((obj = reader.readObject()) != null)
{
    SolsticeMessage message = (SolsticeMessage) obj;
    processMessage(message);
}

...しかし、あなたはそれをString最初に送っています。したがって、をにキャストしようとするStringSolsticeMessage、例外がスローされます。おそらくプロセス全体がダウンするか、少なくとも接続が閉じられてしまう可能性があります。

于 2012-11-08T21:11:21.597 に答える