Как я могу читать поток сокетов до новой строки? - PullRequest
0 голосов
/ 05 ноября 2018

У меня есть приложение Node.js server + Unity (.NET 3.5), которое обеспечивает связь между сокетами. У меня возникла проблема при получении данных с сервера Node.js клиенту сокета C #.

Я бы хотел, чтобы мой клиент C # считывал потоки сокетов до тех пор, пока не будет найден разрыв строки (/n). Таким образом я гарантирую поток данных с C # на сервер Node.js, поскольку существует модуль NPM под названием split , который обеспечивает чтение буфера построчно.

Ниже приведен мой код, и я был бы очень признателен, если бы вы могли предложить мне решения для достижения упомянутого способа получения данных:

Здесь я без проблем подключаюсь к серверу Node.js:

private Socket ClientSocket;
private byte[] _receiveBuffer = new byte[8142];

public string hostname;
public int port;

public void onnectClient()
{
    ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    ClientSocket.Connect(hostname, port);
    ClientSocket.BeginReceive(_receiveBuffer, 0, _receiveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}

Текущее значение ReceiveCallback,:

private void ReceiveCallback(IAsyncResult AR)
{
    int received = ClientSocket.EndReceive(AR);
    byte[] recData = new byte[received];
    Buffer.BlockCopy(_receiveBuffer, 0, recData, 0, received);

    string resultString = System.Text.Encoding.UTF8.GetString(recData);

    currentlyReceivedData = JsonUtility.FromJson<ReceivedData>(resultString);

    ClientSocket.BeginReceive(_receiveBuffer, 0, _receiveBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}

ОБНОВЛЕНИЕ 1:

Вместо приведенного выше кода теперь я использую TcpClient и StreamReader, но по какой-то причине пока цикл не продолжается:

    private void ListenForData()
{
    try
    {
        socketConnection = new TcpClient("localhost", 6670);
        Byte[] bytes = new Byte[1024];
        while (true)
        {

            using (StreamReader sr = new StreamReader(socketConnection.GetStream()))
            {
                string line;
                // Read and display lines from the file until the end of 
                // the file is reached.
                while ((line = sr.ReadLine()) != null)
                {
                    Debug.Log("line");
                }
            }
        }
    }
    catch (SocketException socketException)
    {
        Debug.Log("Socket exception: " + socketException);
    }
}

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Если вам не нужно использовать все опции, доступные для Socket, я бы рекомендовал вместо этого использовать класс TcpClient. Как только вы подключитесь, вы можете позвонить GetStream() на него, чтобы получить NetworkStream 1 , который вы можете передать на StreamReader .

Когда вы там, вы можете просто позвонить ReadLine() (или моральный эквивалент), чтобы получить каждую полную строку. Это позволяет вам игнорировать многие реалии работы с «сырым» TCP, такие как необходимость восстанавливать / сохранять буферы для отражения реальности того, что это не обмен сообщениями, а поток байтов.

ReadLine может справиться с любой обычной формой концов строк, включая \n, \r и \r\n.


1 Обратите внимание, что вы можете просто создать один из существующих Socket в качестве альтернативы. Но я стараюсь использовать более простые варианты, если мне не нужна сложность более сложного.

0 голосов
/ 05 ноября 2018

Я бы порекомендовал вам взглянуть на это: https://blogs.msdn.microsoft.com/dotnet/2018/07/09/system-io-pipelines-high-performance-io-in-net/

Это может спасти вас от некоторых неприятностей!

Если вы не можете использовать System.IO.Pipelines, вы все равно можете изучить пример чтения из сокета, пока не достигнете новой строки!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...