java - Java客户端,C#服务器,如何处理接收列表
问题描述
我想要做的是有一个用 Java 编写的客户端(在 Android Studio 中创建的 Android 应用程序的一部分)。单击 android 应用程序中的按钮后,我想使用 TCP 将整个 epcList 发送到服务器:
public class TCPClient {
private String serverMessage;
public static final String SERVERIP = "192.168.102.53";
public static final int SERVERPORT = 12456;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
BufferedReader in;
DataOutputStream dataOutputStream = null;
boolean isConnected = false;
Socket socket = new Socket();
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.print(message);
out.flush();
}
}
public void stopClient(){
mRun = false;
}
public void run(String message) {
mRun = true;
try {
if(!isConnected){
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
socket.setSoTimeout(20000);
Log.e("TCP Client", "Timeout is 20000ms");
socket.setReuseAddress(true);
socket.bind(new InetSocketAddress("0.0.0.0", SERVERPORT));
Log.e("TCP Client", "Socket bound");
socket.connect(new InetSocketAddress(serverAddr, SERVERPORT), 20000);
Log.e("TCP Client", "Socket connected");
if(socket.isBound()){
Log.i("SOCKET", "Socket: Connected");
}
else{
Log.e("SOCKET", "Socket: Not Connected");
}
isConnected = true;
}
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
String str=message;
byte[] data=str.getBytes("UTF-8");
Log.e("data", String.valueOf(data.length));
Log.e("message", message);
dataOutputStream.write(data, 0, data.length);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
if(out.checkError())
{
Log.e("PrintWriter", "CheckError");
}
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
客户端应逐项发送整个 epcList 项:
public class connectTask extends AsyncTask<String, String, TCPClient> {
@Override
protected TCPClient doInBackground(String... message) {
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
@Override
public void messageReceived(String message) {
Log.e("message:", message);
publishProgress(message);
}
});
for(int i=0; i<epcList.size();++i){
mTcpClient.run(epcList.get(i));
//epcList.remove(i);
Log.e("sent", epcList.get(i));
}
return null;
}
epcList 应该由 C# 中的服务器接收:
namespace Server2
{
class Program
{
static Socket listeningSocket;
static Socket socket;
static Thread thrReadRequest;
static int iPort = 12456;
static int iConnectionQueue = 100;
static void Main(string[] args)
{
Console.WriteLine(IPAddress.Parse(getLocalIPAddress()).ToString());
try
{
listeningSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("created listening socket");
//listeningSocket.Bind(new IPEndPoint(0, iPort));
String ip = "192.168.102.53";
//listeningSocket.Bind(new IPEndPoint(IPAddress.Parse(getLocalIPAddress()), iPort));
listeningSocket.Bind(new IPEndPoint(IPAddress.Parse(ip), iPort));
Console.WriteLine("bound listening socket");
listeningSocket.Listen(iConnectionQueue);
Console.WriteLine("listening socket is listening");
thrReadRequest = new Thread(new ThreadStart(getRequest));
Console.WriteLine("new thread getRequest");
thrReadRequest.Start();
Console.WriteLine("started thread");
}
catch (Exception e)
{
Console.WriteLine("Winsock error: " + e.ToString());
//throw;
}
}
static private void getRequest()
{
int i = 0;
while (true)
{
Console.WriteLine("Outside Try i = {0}", i.ToString());
try
{
socket = listeningSocket.Accept();
Console.WriteLine("Connected...");
while (true)
{
try
{
// Receiving
byte[] buffer = new byte[socket.SendBufferSize];
int iBufferLength = socket.Receive(buffer, 0, buffer.Length, 0);
Console.WriteLine("Received {0}", iBufferLength);
Array.Resize(ref buffer, iBufferLength);
string formattedBuffer = Encoding.ASCII.GetString(buffer);
List<string> myList = formattedBuffer.Split("\r\n").ToList();
Console.WriteLine("Android Says: {0}", formattedBuffer);
if (formattedBuffer == "quit")
{
socket.Close();
listeningSocket.Close();
Console.WriteLine("Exiting");
Environment.Exit(0);
}
//Console.WriteLine("Inside Try i = {0}", i.ToString());
Thread.Sleep(500);
i++;
}
catch (Exception e)
{
//socket.Close();
Console.WriteLine("Receiving error: " + e.ToString());
Console.ReadKey();
//throw;
}
}
}
catch (Exception e)
{
socket.Close();
Console.WriteLine("Error After Loop: " + e.ToString());
//throw;
}
finally
{
Console.WriteLine("Closing Socket");
socket.Close();
listeningSocket.Close();
}
}
}
static private string getLocalIPAddress()
{
IPHostEntry host;
string localIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
break;
}
}
return localIP;
}
}
}
我期望发生的事情:我按下应用程序中的按钮,然后我的手机连接到我的 PC 上的服务器并发送 epcList。然后接收该列表并将其打印在屏幕上。
现实中发生的事情是:
我认为客户端正确发送了 epcList(4 个元素的列表)(下面的 Logcat)
2021-01-25 13:34:25.559 382-504/ E/TCP 客户端:C:正在连接...
2021-01-25 13:34:25.559 382-504/ E/TCP Client: Created new socket 2021-01-25 13:34:25.560 382-504/ E/TCP Client: Timeout is 20000ms 2021-01-25 13:34:25.561 382-504/ E/TCP Client: Socket bound 2021-01-25 13:34:25.574 382-504/ E/TCP Client: Socket connected 2021-01-25 13:34:25.575 382-504/ E/data: 24 2021-01-25 13:34:25.575 382-504/ E/message: E2801160600002085A0A6360 2021-01-25 13:34:25.575 382-504/ E/TCP Client: C: Sent. 2021-01-25 13:34:25.575 382-504/ E/TCP Client: C: Done. 2021-01-25 13:34:25.576 382-504/ E/RESPONSE FROM SERVER: S: Received Message: 'null' 2021-01-25 13:34:25.576 382-504/ E/sent: E2801160600002085A0A6360 2021-01-25 13:34:25.576 382-504/ E/data: 24 2021-01-25 13:34:25.576 382-504/ E/message: E2801160600002085A0A6390 2021-01-25 13:34:25.576 382-504/ E/TCP Client: C: Sent. 2021-01-25 13:34:25.576 382-504/ E/TCP Client: C: Done. 2021-01-25 13:34:25.577 382-504/ E/RESPONSE FROM SERVER: S: Received Message: 'null' 2021-01-25 13:34:25.577 382-504/ E/sent: E2801160600002085A0A6390 2021-01-25 13:34:25.577 382-504/ E/data: 24 2021-01-25 13:34:25.577 382-504/ E/message: E2801160600002085A0A6330 2021-01-25 13:34:25.577 382-504/ E/TCP Client: C: Sent. 2021-01-25 13:34:25.577 382-504/ E/TCP Client: C: Done. 2021-01-25 13:34:25.577 382-504/ E/RESPONSE FROM SERVER: S: Received Message: 'null' 2021-01-25 13:34:25.578 382-504/ E/sent: E2801160600002085A0A6330 2021-01-25 13:34:25.578 382-504/ E/data: 24 2021-01-25 13:34:25.578 382-504/ E/message: E2801160600002085A0A6380 2021-01-25 13:34:25.578 382-504/ E/TCP Client: C: Sent. 2021-01-25 13:34:25.578 382-504/ E/TCP Client: C: Done. 2021-01-25 13:34:25.578 382-504/ E/RESPONSE FROM SERVER: S: Received Message: 'null' 2021-01-25 13:34:25.578 382-504/ E/sent: E2801160600002085A0A6380
服务器仅正确读取列表中的第一项,其余的被视为非常长的字符串。我不知道可能是什么原因(从下面的控制台输出)
192.168.56.1 created listening socket bound listening socket listening socket is listening new thread getRequest started thread Outside Try i = 0 Connected... Received 24 Android Says: E2801160600002085A0A6360 Received 72 Android Says: E2801160600002085A0A6390E2801160600002085A0A6330E2801160600002085A0A6380
我已经研究了很长时间,但我根本找不到导致这个问题的原因。我将不胜感激任何帮助
解决方案
我看到代码有几个问题
C# 代码在每条消息后都需要回车
'\r\n'
- 我没有看到你已经发送了那个。这就是为什么你会看到一根大绳子。编码不同。在 Java 代码中,您使用了 UTF8,在 C# ASCII 中。
套接字返回它接收到的字节数。因此消息可以分为两个或多个不同的数据包。如果您收到的不是整个消息或整个消息和另一个消息的一部分,则必须进行缓冲。检查具有此类缓冲的此实现https://github.com/davidfowl/TcpEcho
推荐阅读
- database - 在 Oracle 中使用间隔分区对现有表进行分区
- git - PhpStorm 和搁置未跟踪的文件
- powerbi - 如何将超链接添加到 PowerBI 中的对象而不是表中的 http 链接
- c# - 'Microsoft.AspNet.WebPages' 兼容 con 'Microsoft.AspNet.Web.Helpers.Mvc 2.0.20710
- ios - 如何更改导航栏标题的颜色?
- python - 根据匹配列值压缩 DataFrame
- c - 如何使用 SPI 正确发送多个字符串
- java - 带有 RabbitMQ 和 TaskQueue / WorkerQueue 的 Spring-Boot
- r - 提取和绘制数据框的关键列
- c# - IIS7 安装/配置本机模块