首页 > 解决方案 > 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。然后接收该列表并将其打印在屏幕上。

现实中发生的事情是:

我已经研究了很长时间,但我根本找不到导致这个问题的原因。我将不胜感激任何帮助

标签: javac#sockets

解决方案


我看到代码有几个问题

  • C# 代码在每条消息后都需要回车'\r\n'- 我没有看到你已经发送了那个。这就是为什么你会看到一根大绳子。

  • 编码不同。在 Java 代码中,您使用了 UTF8,在 C# ASCII 中。

  • 套接字返回它接收到的字节数。因此消息可以分为两个或多个不同的数据包。如果您收到的不是整个消息或整个消息和另一个消息的一部分,则必须进行缓冲。检查具有此类缓冲的此实现https://github.com/davidfowl/TcpEcho


推荐阅读