我试图使用TCP将json从C#服务器传递到Java服务器,问题是Java服务器第一次似乎收到一个空的json.第二次以及之后它工作正常,请参见下面的输出.欢迎任何想法或建议,谢谢.
输出:
Starting server...
Waiting for a connection..
Connected!
Reading...
Received empty object
Received:
Connected!
Reading...
Received: "Request:gethotellist"
Connected!
Reading...
Received: "Request:gethotellist"
Run Code Online (Sandbox Code Playgroud)
以下是用于发送json的C#代码段:
public void GetHotelList()
{
TcpClient clientSocket = new TcpClient();
clientSocket.Connect("127.0.0.1", 6767);
NetworkStream ns = clientSocket.GetStream();
string jsonRequest = "Request:gethotellist";
string jsonToSend = JsonConvert.SerializeObject(jsonRequest);
byte[] dataBytes = Encoding.UTF8.GetBytes(jsonToSend);
ns.Write(dataBytes, 0, dataBytes.Length);
ns.Close();
}
Run Code Online (Sandbox Code Playgroud)
Java服务器:
public class JHotelServer
{
public static void main(String[] args) throws IOException
{
final int PORT = 6767;
System.out.println("Starting server...");
@SuppressWarnings("resource")
ServerSocket welcomeSocket = new ServerSocket(PORT);
System.out.println("Waiting for a connection..");
while(true)
{
try
{
Socket connectionSocket = welcomeSocket.accept();
System.out.println("Connected!");
Thread connectionThread = new Thread(new TcpConnectionManager(connectionSocket));
connectionThread.start();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是Tcp通讯管理器:
public class TcpConnectionManager implements Runnable
{
private DataInputStream inFromDotNet;
public TcpConnectionManager(Socket socket) throws IOException
{
inFromDotNet = new DataInputStream(socket.getInputStream());
}
@Override
public void run()
{
try
{
System.out.println("Reading...");
byte[] rvdMsgByte = new byte[inFromDotNet.available()];
// Collecting data into byte array
for (int i = 0; i < rvdMsgByte.length; i++)
{
rvdMsgByte[i] = inFromDotNet.readByte();
}
if (rvdMsgByte.length == 0)
{
System.out.println("Received empty object");
}
// Converting collected data in byte array into String.
String rvdMsgTxt = new String(rvdMsgByte);
System.out.println("Received: " + rvdMsgTxt);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据显示的代码,完全可以预期有时会得到一个空的有效载荷,因为如果有效载荷数据包尚未到达:inFromDotNet.available()将为零.
基本上,除了"当前缓冲的字节数"(可能在同步读取和异步读取之间进行选择.available())之外,永远不应该使用(和等效的)来确定有关内容的任何内容.
这里常用两种方法:
Receive返回非正数)如果您每个插槽只发送一条消息,则第一个选项是相关的; 如果您要为每个插槽发送多条消息,则需要第二个选项.基本框架协议可以像"消息由换行符分隔"一样简单,但在许多情况下,您可能需要二进制安全框架,例如长度前缀.例如,您的JSON可能包含换行符,可能会错误地将其解释为帧的结尾.
在任何一种情况下:使用套接字几乎总是需要在循环中读取,因为数据可以分成多个数据包,和/或您的接收缓冲区大小可能太小.通常,您将循环并缓冲所有有效负载,直到您检测到EOF或帧的结尾,然后才开始尝试处理内容.特别是,在您知道自己拥有整个文本之前,通常不应尝试解码文本,因为多字节字符可能跨越多个"读取"/"接收"调用,因此:除非您使用有状态文本解码器,否则可能会错误地解码这些字符
您所看到的行为几乎适用于所有平台和语言; 它不是特定于Java/C#.
| 归档时间: |
|
| 查看次数: |
54 次 |
| 最近记录: |