gpt4 book ai didi

java - 针对蜂窝调制解调器项目的客户端/服务器交互故障排除的建议和帮助

转载 作者:行者123 更新时间:2023-12-01 04:51:18 25 4
gpt4 key购买 nike

我需要一些建议并帮助解决我正在开发的蜂窝调制解调器项目的客户端/服务器交互问题。客户端和服务器都是用Java编写的。

我需要建议的问题如下:

(1) 我正在寻求建议,了解我所采取的方法是否能够扩展大文件(要遵循的代码),特别是在网络可能意外退出的蜂窝网络环境中。大文件约为 1GB。大文件表示从服务器传输到客户端的图像。这代表了最坏的情况。基本情况包含相对较小的文件,其中包含 GPS 数据和时间戳信息。这些文件可能在 KB 到几 MB 范围内,并且经常传输。

(2) 需要有关客户端/服务器代码故障排除的建议。即使这种方法不适用于较大的文件,我也希望让代码适用于基本案例,以支持在不久的将来进行概念验证测试。概念验证不需要软件更新。

客户端/服务器交互的背景知识。客户端联系服务器。服务器检测到客户端请求,启动一个新线程来处理客户端。客户端传输序列化数据包。数据包包含一些 header 信息(文件大小、crc、文件类型)和数据有效负载。收到数据包对象后,服务器验证 crc 和文件大小是否与 header 中包含的值匹配。服务器用数据包对象进行响应,该数据包对象指示传输是否有效。如果客户端收到来自服务器的有效响应,则客户端会发送一个再见数据包以关闭 session 。如果服务器的响应无效,客户端将重新发送数据,并在 x 次失败尝试后最终退出。最终,客户端将从服务器获取一组指令,这些指令可以指示它上传日志文件、下载新的 .jre 文件,甚至新的固件镜像。

这是我在服务器代码上遇到的错误:

Feb 16, 2013 7:36:40 AM noaa.logbook.server.ServerConnectionHandler run
SEVERE: null
java.io.EOFException
at
java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:2553)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1296)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at noaa.logbook.server.ServerConnectionHandler.run(ServerConnectionHandler.java:69)
at java.lang.Thread.run(Thread.java:662)

数据随着服务器到达,看起来下次我尝试读取 objectinputstream 上的对象时发生异常,这是再见数据包。

客户端代码:

public static boolean clientTransmit(Socket sockToServer, String fileName, int dataPacketType, String id, String fileTimeStamp)    {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
//TCPConnection tcpConn = null;
DataPacket packet = null;

File inputFile = new File(fileName);
boolean fileExists = inputFile.exists();

int size = 0;
int failedAttempts = 0;
String contents = null;
byte[] ref = null;
boolean success = false;
boolean bye = false;
try
{
sockToServer.setSoTimeout(5000);

if ((sockToServer.isConnected()) && (fileExists)) {
System.out.println("LogBookClientCommunications: Connected to Server");
System.out.print("Stage 0");
contents = readFile(fileName);

packet = LogBookUtilities.packageDataPacket(DataPacket.UPLOAD_DATA, contents, LogBookClient.SOFTWARE_VERSION, LogBookClient.serialNumber);

oos = new ObjectOutputStream(sockToServer.getOutputStream());
oos.writeObject(packet);
oos.flush();
System.out.println("LogBookClientCommunications: Sending DataPacket");

ois = new ObjectInputStream(sockToServer.getInputStream());

while(!success && failedAttempts < 3) {
Object object = ois.readObject();
if (object instanceof DataPacket) {
System.out.println("LogBookClientCommunications: Received a DataPacket Object");
DataPacket inPacket = (DataPacket)object;
byte[] compressedByteRef = inPacket.getDataArray();
boolean sizeValid = verifySize(compressedByteRef, inPacket.getLength());
boolean crcValid = verifyCRC(inPacket);
if ((sizeValid) && (crcValid)) {
System.out.println("LogBookClientCommunications: Size & CRC Valid");
String uncompressed = new String(uncompress(compressedByteRef));
String[] strRef = lookupResponsePairs(dataPacketType);

if (uncompressed.equals(strRef[0])) {
success = true;
System.out.println("LogBookClientCommunications: File arrived uncorrupted");
//tcpConn.disconnect();
} else if (uncompressed.equals(strRef[1])) {
success = false;
failedAttempts++;
System.out.println("LogBookClientCommunications: File arrived corrupted");
}
} else {
success = false;
failedAttempts++;
if (sizeValid)
System.out.println("LogBookClientCommunications: CRC InValid");
else
System.out.println("LogBookClientCommunications: Size InValid");
}
}//end if object instanceof
else {
System.out.println("LogBookClientCommunications: Not a DataPacket Object");
failedAttempts++;
}
}//while
//Close Connection by sending bye
System.out.println("LogBookClientCommunications: Sending Good Bye...");
DataPacket goodbye = LogBookUtilities.packageDataPacket(DataPacket.RESPONSE, quit", LogBookClient.SOFTWARE_VERSION, LogBookClient.serialNumber);
oos.writeObject(goodbye);
oos.flush();
}
else
{
System.out.println("LogBookClientCommunications: Failed to Connect or File Did Not Exist");
success = false;
}
}
catch (ClassNotFoundException ex) {
Logger.getLogger(LogBookUtilities.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(LogBookUtilities.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
oos.close();
ois.close();
sockToServer.close();
} catch (IOException ex) {
Logger.getLogger(LogBookUtilities.class.getName()).log(Level.SEVERE, null, ex);
}
}
return success;
}

服务器连接处理程序代码:

public void run()
{
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
int failedAttempts = 0;
boolean success = false;
boolean sendResponse = false;
Socket soc = getSocket();
Object obj = new Object();
long time = System.currentTimeMillis();

DataPacket inPacket = null;
DataPacket outPacket = null;
try {
System.out.println("Server Connection Handler: Receiving Connection From - " + soc.getRemoteSocketAddress());
soc.setSoTimeout(15000);
oos = new ObjectOutputStream(soc.getOutputStream());
oos.flush();

ois = new ObjectInputStream(soc.getInputStream());

if (ois == null | oos == null) {
System.out.println("Server Connection Handler: Successfull Opened Streams");
if (ois == null) { System.out.println("Server Connection Handler: ObjectInputStream Failed to Open");}
else {System.out.println("Server Connection Handler: ObjectOutputStream Failed to Open"); }
}
while (true) {
inPacket = (DataPacket)ois.readObject();
boolean validPacket = LogBookUtilities.isPacketValid(inPacket);
if (validPacket) {
if(inPacket.getField() == DataPacket.RESPONSE) {
byte[] ref = inPacket.getDataArray();
String data = LogBookUtilities.uncompress(ref);
if (data.equalsIgnoreCase("bye")) {
System.out.println("Server Connection Handler: Bye....");
break;
}
}
else if (inPacket.getField() == DataPacket.UPLOAD_DATA) {
System.out.println("Server Connection Handler: Writing data to file");
LogBookUtilities.processClientPacket(inPacket);
System.out.println("Server Connection Handler: File Successfully Transfered");
outPacket = LogBookUtilities.makeResponse(inPacket.getField(), true, LogBookServer.SOFTWARE_VERSION, LogBookServer.ID);
sendResponse = true;
}
}
else {
if (inPacket.getField() == DataPacket.UPLOAD_DATA) {
sendResponse = true;
outPacket = LogBookUtilities.makeResponse(inPacket.getField(), true, LogBookServer.SOFTWARE_VERSION, LogBookServer.ID);
}
}

if (sendResponse) {
oos.writeObject(outPacket);
oos.flush();
}

}//end while


}
catch (ClassNotFoundException ex) {
Logger.getLogger(ServerConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger(ServerConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
finally {
try {
ois.close();
oos.close();
soc.close();
}
catch (IOException ex) {
Logger.getLogger(ServerConnectionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

服务器代码:

public class LogBookServer
{
public static final String ID = "666666";
public static final String SOFTWARE_VERSION = "0.02";
public static final String VFILE = "vFile";
public static final String DASH = "-";
public static final String DATEXT = ".dat";
public static final int FAILED_THRESHOLD = 3;
private int port = 6767;
private String ip = "";

public int getListeningPort() {
return this.port;
}

public void setListeningPort(int port) {
this.port = port;
}

public void run()
throws Exception
{
Selector acceptSelector = SelectorProvider.provider().openSelector();

ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);

InetAddress lh = InetAddress.getLocalHost();
InetSocketAddress isa = new InetSocketAddress(lh, this.port);
ssc.socket().bind(isa);

SelectionKey acceptKey = ssc.register(acceptSelector, 16);

int keysAdded = 0;

while ((keysAdded = acceptSelector.select()) > 0)
{
Set readyKeys = acceptSelector.selectedKeys();
Iterator i = readyKeys.iterator();

while (i.hasNext()) {
SelectionKey sk = (SelectionKey)i.next();
i.remove();

ServerSocketChannel nextReady = (ServerSocketChannel)sk.channel();

Socket s = nextReady.accept().socket();

handleConnection(s);
}
}
}

void handleConnection(Socket socket)
{
System.out.println("hadling connection....");
ServerConnectionHandler connectionHandler = new ServerConnectionHandler(socket);
new Thread(connectionHandler).start();
}
}

最佳答案

在您的客户端中,您有(为了可读性分成不同的行):

DataPacket goodbye  = 
LogBookUtilities.packageDataPacket(DataPacket.RESPONSE,
"quit",
LogBookClient.SOFTWARE_VERSION,
LogBookClient.serialNumber);

然后在您的服务器中您有:

if (data.equalsIgnoreCase("bye")) {

其中哪一个与另一个不同? ;)

您的服务器读取“再见”数据包,但无法识别它,然后再次循环并尝试从关闭的套接字读取数据。很快,IOException

至于你的“可扩展性”问题……与其说是效率,不如说是问题。如果您担心网络会从您的脚下掉线,那么发送序列化对象可能不是最佳选择。无法恢复 - 部分发送必须完全重新发送,如果它是您所说的一大堆数据……那很糟糕。您最好使用具有合理缓冲区大小的 OutputStreamwrite() 方法。这将允许您跟踪已发送的数据,并在网络恢复后恢复传输(显然,这将需要在客户端和服务器之间实现一些逻辑,以便您可以弄清楚服务器已经收到了什么网络故障的情况下)。

关于java - 针对蜂窝调制解调器项目的客户端/服务器交互故障排除的建议和帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14915962/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com