C # Программирование сокетов, полученная длина сокетов неверна - PullRequest
0 голосов
/ 01 ноября 2019

Я делаю приложение чата между клиентами C # и java-сервером.

Мне нужно отправить много сокетов с сервера на клиент при подключении. Я хочу отправить журналы дня. Итак, у меня есть все журналы в файле file.txt, и я отправляю их новому подключенному клиенту.

Для их отправки у меня есть цикл for, пока не будут отправлены все журналы. Вот цикл:

    for (String item : Logs) {
        client.send("log:" + item);
    }

И для метода отправки:

public void send(String text) {
    //'os' is the: Socket.getOutputStream();
    //What the server will send to the client
    PrintWriter Out = new PrintWriter(os);
    //              0 is the offset, not needed
    Out.write(text, 0, text.length());
    Out.flush();
    System.out.println(text.length());
}

Так что пока все работает хорошо.

Теперь моя проблема: выходной поток посылает длину в байтах, например, '30', '100 ',' 399 ', который является' text.length () ', и клиент C # получает все сокеты, но вставляет 2 или 3 сокета в один .

Например: если я отправляюс разделенными сокетами (каждая строка является out.write () и out.flush (), потому что я вызываю метод send для каждой строки) (на стороне сервера)

log:abcdefghijklmnopqrstuvwxyz123456789101112131415
log:abcdefghijklmnopqrstuvwxyz
log:abcdefghijklmnopqrstuvwxyz123456789101
log:abcdefghijklmnopqrstuvwxyz1234567891011121314151617
log:abcdefghijklmnopqrst
log:abcdefghijklmnopqrstuvwxyzyxwvu

сокетов будет в конце : (на стороне клиента)

log:abcdefghijklmnopqrstuvwxyz123456789101112131415log:abcdefghijklmnopqrstuvwxyzlog:abcdefghijklmnopqrstuvwxyz123456789101

log:abcdefghijklmnopqrstuvwxyz1234567891011121314151617log:abcdefghijklmnopqrst

log:abcdefghijklmnopqrstuvwxyzyxwvu

И если я проверю длина сокетов на стороне сервера Я получаю как;

20
12
15
17
20

Но на стороне клиента ;

32
15
37

Сумма кратных сокетов, собранных вместе. (А иногда это 3 сокета, вместе взятые, а иногдаs 2, иногда 4 ...) Я не могу понять, почему ...

Вот мой асинхронный метод для получения сокетов с сервера ;

    private void callBack(IAsyncResult aResult)
    {
        String message = "";
        try
        {
            int size = sck.EndReceiveFrom(aResult, ref ip);
            if (size > 0)
            {
                byte[] receive = new byte[size];
                receive = (byte[])aResult.AsyncState;
                message = Encoding.Default.GetString(receive, 0, size);
                Debug.WriteLine(message.Length);
            }
            byte[] buffer = new byte[1024];
            //restart the async task
            sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref ip, new AsyncCallback(callBack), buffer);
        }
        catch (Exception) { }
    }

Где int 'size' содержит размер полученного байта [], и здесь проблема. Как я могу получить правильные сокеты, которые я отправил с сервера?

Если я отправляю каждый сокет с задержкой на стороне сервера (например, 15 мс), клиент может получить розетки один за другим . Но только если у вас хорошее соединение . Если ваше соединение имеет задержку 200 мс, вы сгруппируете сокеты ... Так что проблема на стороне клиента (я думаю ...). Серверная (java) сторона работает правильно, метод flush всегда отправляет сокет!

ОБНОВЛЕНИЕ:

Вот мои сокеты ;

    //Global var
    EndPoint ip;
    public Socket sck;

    //How I connect my sockets
    private void connect()
    {
        ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), mysql.selectPort());
        sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        try
        {
            sck.Connect(ip);
        }catch(Exception e) {
            Debug.WriteLine(e.Message);
        }
    }
...