简体   繁体   中英

Java client, C# server, how to handle receiving a list

What I'm trying to do is having a client written in Java (part of Android app created in Android Studio). After clicking on a button in android app I want to send a whole epcList to server using 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 && !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);
}

}

The client should send a whole epcList item after item:

 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;
    }

The epcList should be received by a server in 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;
    }

}

}

What I expect to happen: I press the button in my app, then my mobile connects to server on my PC and sends epcList. This list is then received and printed on the screen.

What happens in reality is:

  • I think that the client sends the epcList (a list of 4 elements) correctly (Logcat below)

    2021-01-25 13:34:25.559 382-504/ E/TCP Client: C: Connecting...

     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
  • server reads correctly only the first item in the list, the rest is treated like a very long String. I have no idea what may be the cause (output from the console below)

     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

I have been working on it for a long time and I simply cannot find what is causing this problem. I would appreciate any help

I see several problems with the code

  • C# code expects carriage return after each message '\r\n' - I do not see that you have sent that. That's why you see one big string.

  • Encodings are different. In Java code you have used UTF8, in C# ASCII.

  • Socket returns as many bytes as it receives. So message can be divided in two or more different packets. You have to do buffering if you received not whole message or whole message and part of another. Check this implementation which has such buffering https://github.com/davidfowl/TcpEcho

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM