サーバー側のソケット処理コードを書きましたが、パケットが常にクライアントに返されるとは限らないのではないかと心配しています。すべてのイベントをログに記録していますが、ログ ファイルに情報を送信していると表示されます。しかし、クライアントはイベントもログに記録しており、ログには何も受信していないと書かれています。
データを送信するための私のコードは次のとおりです。
public void write(Packet packet) {
String data = packet.serialize();
log("Send=[" + data + "]", "Write"); // log to file
try {
_writer.write(data);
_writer.flush();
} catch (Exception ex) {
log(ex, "write");
}
}
各ソケットは新しいスレッドで作成され、ライターとリーダーを次のようにすぐに作成します (public run メソッドで):
// _sockt is a Java Socket object
_writer = new BufferedWriter(new OutputStreamWriter(_socket
.getOutputStream()));
_reader = new SocketReader(_socket);
SocketReader は、応答をリッスンするために作成した単なるラッパー クラスであり、次のような public read メソッドがあります。
public String read() throws IOException, SocketTimeoutException {
_socket.setSoTimeout(_timeOut);
if(_reader == null)
_reader = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
// read from the stream
return new PacketDataInputStream(_reader).read();
}
PacketDataInputStream ラッパー クラス:
BufferedReader _reader = null;
public PacketDataInputStream(BufferedReader reader)
{
_reader = reader;
}
public String read() throws IOException, SocketException {
StringBuilder builder = new StringBuilder();
int c = 0;
while((c = _reader.read()) != -1)
{
char ch = (char)c;
builder.append(ch);
if(ch == PacketConstants.ETX)
break;
}
if(builder.length() > 0)
return builder.toString();
else
return null;
}
実際のソケットリスナーオブジェクトを作成する方法は、かなり標準的だと思います:
InetAddress address = InetAddress.getByName(IP);
server = new ServerSocket( port, 0, address);
// My own manager class to handle all the sockets connected
WebSocketManager manager = new WebSocketManager(this);
Socket connection = null;
while(bContinue)
{
connection = server.accept();
if(bContinue) {
// assign the socket to a new thread and start
// that thread
manager.newSocket(connection);
} else {
connection.close();
}
}
- データを送り返すために間違ったオブジェクトを使用している可能性があります。
- bufferedwriter と reader を使用する必要がありますか? これらが最善の方法だと思っていましたが、今はよくわかりません。
これは常に発生するわけではなく、散発的に発生することに注意することが重要です。クライアントのコードにバグがある可能性がありますが、クライアントに戻る前に、正しく実行していることを確認する必要があります。
このコードは、Linux Ubuntuサーバーで実行されます。ログはテキスト ファイルに記録されますが、特別なことは何もありません。私のログ ファイルには、Send=""データがクライアントに返され、例外がないことが示されているため、.write と .flush() が機能したように見えますか? ソケット接続は永続的であり、クライアントまたはネットワークの問題によってのみ閉じられます。
更新 ----- クライアント側のコード -------:
私は、データの送受信をどのように処理しているかについて、クライアント側のコードの一部を取得することができました (念のため、クライアント側でより明白な場合に備えて)。クライアントは、実際にはAndroid デバイスを介してこのサーバーに接続しています(それが役立つ場合)。
ソケットの作成
static final int BUFFER_SIZE = 20000; // Maximum packet size
java.net.InetAddress server = java.net.InetAddress.getByName(url);
socket = new Socket(server, port);
// Set socket options:
socket.setReceiveBufferSize(BUFFER_SIZE);
socket.setSendBufferSize(BUFFER_SIZE);
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);
送信:
try {
// Send the packet:
OutputStream stream = socket.getOutputStream();
stream.write(p.getByteArray ());
stream.flush();
// Update the time:
lastPacketSendTime = new Date ();
} catch (IOException e) {
setError("Error sending packet (" + e.getMessage() + ")", ERROR_IO);
return false;
}
受信:
socket.setSoTimeout(timeout);
// Get the reader:
inputStream = socket.getInputStream();
while (true) {
// Get the next character:
int value = inputStream.read();
// Check for -1, indicating that the socket is closed:
if (value == -1) {
// The socket is closed remotely, so close it locally as well:
disconnect();
inputStream = null;
return null;
}
// ... and a bunch of other stuff to handle the actual data
}
EDIT 14-11月: これは実際には、より大きな問題であることが証明されています. クライアント ログとサーバー ログの両方が送信されているようです。しかし、データが届かないように見えたり、届いたとしても 10 ~ 30 ~ 60 秒遅れて届くことがあります。
必要に応じて、さらに情報を提供できます。