Home > other >  Socket server doesn't read data a second time
Socket server doesn't read data a second time

Time:10-06

I am trying to create an asynchronous socket server with using c#

The client socket is written in Java

The problem is that when the client connects to the server for the second time, it cannot read the message from client

I also noticed that this happens when I try to send data to the server specifically from the getKey() function

The result of the first and second connections:

enter image description here

server code:

public class SocketServer : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8899);
        Socket socketServer = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

        socketServer.Bind(ipEndPoint);
        socketServer.Listen(100);

        while (!stoppingToken.IsCancellationRequested)
        {
            Socket socketClient = await socketServer.AcceptAsync();

            Console.WriteLine("Client connected");
            processClientTearOff(socketClient);
        }
    }

    async Task processClientTearOff(Socket socket)
    {
        using (var client = new Client(socket))
            await client.ProcessAsync();
    }

    class Client : IDisposable
    {
        Socket socketClient;

        public Client(Socket socketClient)
        {
            this.socketClient = socketClient;
        }

        public void Dispose()
        {
            Console.WriteLine("Client dispose");
            if (socketClient != null)
            {
                socketClient.Disconnect(false);
                socketClient.Shutdown(SocketShutdown.Both);
                socketClient.Close();
                socketClient.Dispose();
                socketClient = null;
            }
        }

        bool SocketConnected()
        {
            if (socketClient == null || !socketClient.Connected)
                return false;
            bool part1 = socketClient.Poll(1000, SelectMode.SelectRead);
            bool part2 = (socketClient.Available == 0);
            if (part1 && part2)
                return false;
            else
                return true;
        }

        public async Task ProcessAsync()
        {
            while (SocketConnected())
            {
                await JavaClient();
            }
        }

        async Task JavaClient()
        {
            string a = await ReadUTF();

            WriteUTF(a);
        }

        async Task WriteUTF(string data)
        {
            Console.WriteLine($"[ ] Write : {data}");
            byte[] bytes = Encoding.UTF8.GetBytes(data);
            byte[] bytesLength = BitConverter.GetBytes(bytes.Length);

            Array.Reverse(bytesLength, 0, bytesLength.Length);

            await socketClient.SendAsync(bytesLength, SocketFlags.None);
            await socketClient.SendAsync(bytes, SocketFlags.None);
        }

        async Task<string> ReadUTF()
        {
            byte[] buf = new byte[4];
            int bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
            int totalBytesRec = 0;
            StringBuilder builder = new StringBuilder();
            if (4 == bytesRec)
            {
                int len = ReverseInt(buf);
                buf = new byte[len];
                do
                {
                    bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
                    totalBytesRec  = bytesRec;
                    builder.Append(Encoding.UTF8.GetString(buf, 0, bytesRec));
                } while (totalBytesRec < len && bytesRec > 0);
            }

            string result = builder.ToString();
            Console.WriteLine($"[ ] Read : {result}");
            return result;
        }

        int ReverseInt(byte[] array)
        {
            var bytes = new byte[array.Length];
            array.CopyTo(bytes, 0);
            if (BitConverter.IsLittleEndian)
                Array.Reverse(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
    }
}

client code:

public static void main(String[] args)
{
    try
    {
        Socket s = new Socket(IP, PORT);
        final DataInputStream in = new DataInputStream(s.getInputStream());
        final DataOutputStream out = new DataOutputStream(s.getOutputStream());

        String key = getKey(); // key = A5E5F7B526C52014323E17B1BAEA406C
        writeUTF(out, key);

        System.out.println(readUTF(in));
    }
    catch (Exception exception)
    {
        exception.printStackTrace();
    }
}

    public static String getKey() {
        try {
            MessageDigest hash = MessageDigest.getInstance("MD5");
            String s = System.getenv("COMPUTERNAME")   System.getenv("PROCESSOR_IDENTIFIER")
                      System.getenv("PROCESSOR_ARCHITECTURE")   System.getenv("NUMBER_OF_PROCESSORS");
            return bytesToHex(hash.digest(s.getBytes()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
    private static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j  ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = HEX_ARRAY[v >>> 4];
            hexChars[j * 2   1] = HEX_ARRAY[v & 0x0F];
        }
        return new String(hexChars);
    }

public static void writeUTF(DataOutputStream out, String str) throws Exception {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        out.writeInt(bytes.length);
        out.write(bytes);
    }

    public static String readUTF(DataInputStream in) throws Exception {
        int length = in.readInt();
        byte[] bytes = new byte[length];
        int totalBytesRec = 0;
        int bytesRec = 4;

        StringBuilder builder = new StringBuilder();
        do {
            bytesRec = in.read(bytes);
            totalBytesRec  = bytesRec;
            builder.append(new String(bytes, 0, bytesRec, StandardCharsets.UTF_8));
        } while (totalBytesRec < length && bytesRec > 0);
        return builder.toString();
    }

CodePudding user response:

You need to change your ReadUTF method on server

    async Task<string> ReadUTF()
    {
        byte[] buf = new byte[4];
        int totalBytesRec = 0;
        do
        {
           byte[] tmp= new byte[1];
           int bytesRec = await socketClient.ReceiveAsync(tmp, SocketFlags.None);
           if(bytesRec>0){
              buff[totalBytesRec  ]=tmp[0];
           }
        } while (4 == totalBytesRec);
        totalBytesRec = 0;
        StringBuilder builder = new StringBuilder();
        int len = ReverseInt(buf);
        buf = new byte[len];
        do
        {
            bytesRec = await socketClient.ReceiveAsync(buf, SocketFlags.None);
            totalBytesRec  = bytesRec;
            builder.Append(Encoding.UTF8.GetString(buf, 0, bytesRec));
        } while (totalBytesRec < len && bytesRec > 0);
        

        string result = builder.ToString();
        Console.WriteLine($"[ ] Read : {result}");
        return result;
    }
  • Related