[英]Android TCP Client/Server not passing messages properly (Only first received)
[英]TCP client/server only receives first two messages
我正在為bukkit設置服務器/客戶端交互。 定制的Minecraft客戶端將通過套接字將數據發送到服務器,服務器將讀取該數據並將消息發送回客戶端。 客戶端和服務器的套接字具有相同的代碼,但是客戶端使用客戶端類,服務器使用服務器。
這是服務器代碼
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import com.cmg.sapphire.sockets.events.ServerSocketAccepted;
import com.cmg.sapphire.sockets.events.ServerSocketAcceptedEvent;
import com.cmg.sapphire.sockets.events.ServerSocketStarted;
import com.cmg.sapphire.sockets.events.ServerSocketStartedEvent;
import com.cmg.sapphire.sockets.events.SocketHandlerReadyEvent;
import com.cmg.sapphire.sockets.events.SocketHandlerReadyEventListener;
public class Server extends Thread {
private int port;
private int counter = 0;
private List<SocketHandler> handlers = new ArrayList<SocketHandler>();
private ServerSocket server;
private ServerSocketStarted started;
private ServerSocketAccepted accepted;
public Server(int port) {
this.port = port;
this.started = new ServerSocketStarted();
this.accepted = new ServerSocketAccepted();
}
private void StartListening() {
try {
server = new ServerSocket(port);
started.executeEvent(new ServerSocketStartedEvent(this));
while (true) {
Socket sock = server.accept();
final SocketHandler handler = new SocketHandler(sock, ++counter);
handler.getReady().addSocketHandlerReadyEventListener(
new SocketHandlerReadyEventListener() {
@Override
public void socketHandlerReady(
SocketHandlerReadyEvent evt) {
accepted.executeEvent(new ServerSocketAcceptedEvent(
this, handler));
}
});
handler.start();
handlers.add(handler);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void ShutdownAll() {
for (SocketHandler handler : handlers) {
handler.Disconnect();
}
handlers.clear();
}
public void StopServer() {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public SocketHandler[] getHandlers() {
return handlers.toArray(new SocketHandler[handlers.size()]);
}
public SocketHandler getHandler(int index) {
return handlers.get(index);
}
public ServerSocketStarted getServerSocketStarted() {
return started;
}
public ServerSocketAccepted getSocketAccepted() {
return accepted;
}
@Override
public void run() {
StartListening();
}
}
這是客戶代碼
import java.net.Socket;
public class Client {
private Socket sock;
private SocketHandler handler = new SocketHandler();
private String host;
private int port;
public Client(String host, int port) {
this.host = host;
this.port = port;
}
public void Connect() {
try {
sock = new Socket(host, port);
handler.setSocket(sock);
handler.setID(0);
handler.start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public synchronized void SendMessage(String message) {
handler.SendMessage(message);
}
public void Disconnect() {
handler.Disconnect();
}
public SocketHandler getHandler() {
return handler;
}
public Socket getSocket() {
return sock;
}
}
這是套接字處理程序類
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import com.cmg.sapphire.main.PvpDojoClient;
import com.cmg.sapphire.sockets.events.MessageReceived;
import com.cmg.sapphire.sockets.events.MessageReceivedEvent;
import com.cmg.sapphire.sockets.events.SocketConnected;
import com.cmg.sapphire.sockets.events.SocketConnectedEvent;
import com.cmg.sapphire.sockets.events.SocketDisconnected;
import com.cmg.sapphire.sockets.events.SocketDisconnectedEvent;
import com.cmg.sapphire.sockets.events.SocketHandlerReady;
import com.cmg.sapphire.sockets.events.SocketHandlerReadyEvent;
public class SocketHandler extends Thread {
private Socket sock;
private int bytesReceived = 0;
private int messageSize = -1;
private byte[] buffer = new byte[4];
private InputStream in;
private OutputStream out;
private SocketConnected connected;
private SocketDisconnected disconnected;
private MessageReceived message;
private SocketHandlerReady ready;
private String hostName;
private int id;
public SocketHandler() {
this.disconnected = new SocketDisconnected();
this.message = new MessageReceived();
this.connected = new SocketConnected();
this.ready = new SocketHandlerReady();
}
public SocketHandler(Socket sock, int id) {
this.sock = sock;
this.id = id;
this.connected = new SocketConnected();
this.disconnected = new SocketDisconnected();
this.message = new MessageReceived();
this.ready = new SocketHandlerReady();
}
private void HandleConnection() {
if (sock == null) {
return;
}
try {
this.hostName = sock.getInetAddress().getCanonicalHostName();
in = sock.getInputStream();
out = sock.getOutputStream();
if (in == null || out == null) {
Disconnect();
return;
}
ready.executeEvent(new SocketHandlerReadyEvent(this, this));
connected.executeEvent(new SocketConnectedEvent(this, this, id));
startReading();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void SendMessage(String message) {
if (sock.isConnected() && !sock.isClosed()) {
writeToStream(message);
}
}
private void startReading() {
if (!sock.isConnected() || sock.isClosed()) {
Disconnect();
return;
}
buffer = new byte[buffer.length - bytesReceived];
try {
if (bytesReceived == -1) // end of stream
{
Disconnect();
return;
}
bytesReceived += in.read(buffer);
if (messageSize == -1) // still reading size of data
{
if (bytesReceived == 4) // received size information
{
messageSize = ByteBuffer.wrap(buffer).getInt(0);
if (messageSize < 0) {
throw new Exception();
}
buffer = new byte[messageSize];
bytesReceived = 0;
}
if (messageSize != 0) // need more data
{
startReading();
}
} else {
if (bytesReceived == messageSize) // message body received
{
StringBuffer sb = new StringBuffer();
sb.append(new String(buffer));
message.executeEvent(new MessageReceivedEvent(this, id, sb
.toString()));
// reset
bytesReceived = 0;
messageSize = -1;
buffer = new byte[4];
startReading(); // start reading again
} else
// need more data
{
startReading();
}
}
} catch (Exception e) {
}
}
private void writeToStream(String message) {
if (!sock.isConnected() || sock.isClosed() || out == null)
return;
byte[] sizeinfo = new byte[4];
byte[] data = message.getBytes();
ByteBuffer bb = ByteBuffer.allocate(sizeinfo.length);
bb.putInt(message.getBytes().length);
try {
out.write(bb.array());
out.write(data);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void Disconnect() {
try {
System.out.println("Client disconnecting");
sock.shutdownInput();
sock.shutdownOutput();
sock.close();
disconnected.executeEvent(new SocketDisconnectedEvent(this, id));
} catch (Exception e) {
e.printStackTrace();
}
}
public void setSocket(Socket sock) {
this.sock = sock;
}
public void setID(int id) {
this.id = id;
}
public String getHostName() {
return hostName;
}
public SocketConnected getConnected() {
return connected;
}
public SocketDisconnected getDisconnected() {
return disconnected;
}
public MessageReceived getMessage() {
return message;
}
public Socket getSocket() {
return sock;
}
public SocketHandlerReady getReady() {
return ready;
}
public void run() {
if (this.sock == null)
return;
HandleConnection();
}
}
最后設置服務器,我有一個運行此代碼的bukkit插件
server.getSocketAccepted().addServerSocketAcceptedEventListener(
new ServerSocketAccepted());
server.getServerSocketStarted().addServerSocketStartedEventListener(
new ServerSocketStarted());
server.start();
然后是客戶端,這是在自定義的minecraft客戶端中
client.Connect();
client.getHandler().getConnected()
.addSocketConnectedEventListener(new SocketConnectedToServer());
client.getHandler().getMessage()
.addMessageReceivedEventListener(new MessageReceived());
client.getHandler().getDisconnected()
.addSocketDisconnectedEventListener(new SocketDisconnected());
要將消息從服務器發送到客戶端,反之亦然,我將在SocketHandler類中調用SendMessage方法。
現在的問題是,當我嘗試向客戶端發送消息時,客戶端只會收到前兩個消息。
客戶將首先向客戶發送一條消息,要求像這樣的播放器套件
GETKIT <player-name>
服務器將接收到該信息,然后像這樣發送回相關數據
KIT <player-name> <kit-name>
然后,客戶端將收到與上述相同的內容。 但是,客戶端每400毫秒向服務器發送大約6個請求,然后服務器將做出相應的響應,但是問題是客戶端將僅接收服務器首次發送的前2條消息,然后再接收其他每個請求-沒有被客戶端接收。
試試這個:(客戶端)
sock.setKeepAlive(true);
您沒有顯示任何端口號,所以我要問的是,該端口號等於bukkit服務器嗎?因為它不能是...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.