2010-01-03 3 views
1

다음 내용에 도움이 필요합니다. 이것은 비동기 소켓과 관련이 있습니다. 보낸 사람에서C# 무효 ReceiveData (IAsyncResult iar)

은 :

볼 수 있습니다 여기에
string stringData = "Welcome to my server server server"; 
byte[] message1 = Encoding.ASCII.GetBytes(stringData); 

//MessageBox.Show(message1.Length.ToString()); 

client.BeginSend(message1, 0, message1.Length, SocketFlags.None, new AsyncCallback(SendData), client); 

의 message.length 찾을 수 있습니다.

- 클라이언트에

:

Socket remote = (Socket)iar.AsyncState; 
    int recv = remote.EndReceive(iar); 
    string stringData = Encoding.ASCII.GetString(data, 0, recv); 

내 질문은 전체 메시지를 받았습니다 될 때까지 전송되는 데이터의 실제 길이에 액세스하고 전화를 받게되며 데이터를 기반으로하는 방법이 ?

답변

7

아니오 - TCP/IP는 스트림 프로토콜입니다. 한 번의 호출로 데이터를 보냈다 고해서 하나의 패킷으로 전송되거나 다른 패킷과 병합되지는 않습니다. 즉, "X"다음에 "Y"를 보내는 것은 "XY"를 전송하는 것과 같습니다. 정확히 같은 패킷으로 전송 될 수 있습니다. 상대방과 구별 할 수 없습니다.

개개의 "메시지"라는 생각을 스트림에 넣고 싶다면 그 데이터의 길이 앞에 명시 적으로 몇 바이트를 붙여야합니다. (다른 방법으로는 구분 기호를 사용하는 것이지만 길이 접두어를 사용하는 것이 훨씬 더 좋습니다. 얼마나 많은 데이터를 수신했는지 쉽게 알 수 있으므로 다음 메시지를 사용하기 시작하는 것에 대해 걱정할 필요가 없습니다. 어떤 형태로 구분 기호를 이스케이프하는 것에 대해 걱정할 필요가 없습니다.)

+0

접두어 대신 여기에 언급 된대로 루프를 구현했습니다. http://stackoverflow.com/questions/582550/c-begin-endreceive-how -do-i-read-large-data. 그것은 일하는 것 같다! :) – iTEgg

+0

소켓이 닫힐 때까지 모든 데이터를 받기를 원한다면 루핑을 계속할 수 있습니다. 그렇지 않으면 실사 *를 보았을 때 알 수 없습니다. 연결에서 하나의 요청/응답 만하는 것이 좋지만 각 방향에서 여러 메시지가있는 "대화"유형의 프로토콜에서는 작동하지 않습니다. –

0

길이를 전달하기 위해 무언가가 전송 된 경우에만 - 길이를 메시지에 미리 지정하거나 일종의 종결 자 문자를 보내십시오.