Клиент Java, сервер C #, как обрабатывать получение списка

#java #c# #sockets

#java #c# #сокеты

Вопрос:

То, что я пытаюсь сделать, — это создать клиент, написанный на Java (часть приложения для Android, созданного в Android Studio). После нажатия на кнопку в приложении для Android я хочу отправить весь список epcList на сервер с использованием TCP:

 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 amp;amp; !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("rn").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;
    }

}

}
 

Что я ожидаю: я нажимаю кнопку в своем приложении, затем мой мобильный телефон подключается к серверу на моем ПК и отправляет 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
     

Я работаю над этим в течение длительного времени, и я просто не могу найти причину этой проблемы. Я был бы признателен за любую помощь

Комментарии:

1. Вы должны отправить длину списка, прежде чем отправлять отдельные значения. Если я чего-то не упустил.

Ответ №1:

Я вижу несколько проблем с кодом

  • Код C # ожидает возврата каретки после каждого сообщения 'rn' — я не вижу, что вы отправили это. Вот почему вы видите одну большую строку.
  • Кодировки разные. В коде Java вы использовали UTF8 в C # ASCII.
  • Сокет возвращает столько байтов, сколько он получает. Таким образом, сообщение может быть разделено на два или более разных пакета. Вы должны выполнить буферизацию, если вы получили не целое сообщение или целое сообщение, а часть другого. Проверьте эту реализацию, которая имеет такую буферизацию https://github.com/davidfowl/TcpEcho

Комментарии:

1. Предоставленная вами ссылка помогла мне с моей проблемой, спасибо