2016-08-24 3 views
1

У меня проблема, что я хочу отправить большую строку через SocketConnection, но я не могу получить строку сразу, потому что сеть ограничена до 1500 байтов, так как я могу получить все байты над Socket без использования TCPClient, или это просто невозможно.Как получить большой поток данных через соединение сокета - без TCPClient

public string ReceiveString(Socket connection) 
    { 
     byte[] buffer = new byte[1048576]; 
     int recBytes = connection.Receive(buffer); 
     return UnicodeEncoding.Unicode.GetString(buffer, 0, recBytes); 
    } 

Thats, что я до сих пор.

Если это невозможно, чтобы получить его через Socket, могу ли я получить EndPoint из Socket, чтобы использовать TCPClient как «последний вариант»?

+0

Вам нужно буквально реализовать [уровень протокола] (https://en.wikipedia.org/wiki/OSI_model#Layer_4:_Transport_Layer) самостоятельно, чтобы разделить данные на пакеты и получить (объединить) их. – Sinatr

+0

Вы не можете. TCP разбивает каждое сообщение на дейтаграммы ~ 1500 байт. Вы используете синхронный метод Receive(), когда вы должны использовать асинхронный метод. Вам нужно добавить завершающий символ к вашей функции передачи, чтобы функция приема могла продолжить чтение 1500 дейтаграмм до тех пор, пока не будут найдены конечные символы. – jdweng

+0

Не имеет ли TCP какой-то конечной последовательности, о которой я говорил, я слышал что-то о \ 0? – Silent3241

ответ

3

TCP - это поток байтов, он не имеет понятия сообщений. Размер отдельных пакетов на проводе не имеет значения, это всего лишь деталь реализации сетевого оборудования. TCP гарантирует, что вы отправляете то, что вы получаете (но нет отношения 1 к 1 между размером отдельных отправлений и размером отдельных чтений, например, в UDP).

Решение требует, чтобы отправитель записывал строковые данные таким образом, чтобы читатель мог знать, когда прекратить чтение. Либо:

  1. отправьте длину строки перед отправкой строковых данных. Затем читатель может сначала прочитать длину, а затем прочитать указанное количество следующих байтов.

  2. a. завершите строку уникальным разделителем, который не может появиться в самой строке. Читатель может продолжить чтение, пока не встретит разделитель.

    b. ограничителем может быть закрытие соединения. Читатель может продолжать чтение до обнаружения разъединения.

Какое решение необходимо использовать, зависит от конкретного протокола, который вы используете. # 1 лучше всего подходит для двоичных протоколов и позволяет эффективно управлять памятью, тогда как # 2 больше подходит для текстовых протоколов или потоковых протоколов, где конечная длина не знает заранее. Иногда протоколы должны прибегать к # 2b (HTTP и FTP используют как время), когда # 1 и # 2a невозможны.

+0

Или переключитесь на протокол более высокого уровня, построенный поверх TCP, который реализует обмен сообщениями/кадрирование. –

+0

@Damien_The_Unbeliever вы, вероятно, думаете больше о библиотеке заранее, чем о протоколе. Если вы просто разрабатываете/принимаете протокол обмена сообщениями, вам все равно придется реализовать код для отправки и чтения кадрового сообщения. –

+0

Ну, я думал о «переключении на HTTP» или аналогичном. То есть протокол, построенный поверх TCP, который уже имеет концепцию обмена сообщениями. –

Смежные вопросы