2012-08-07 3 views
1

향후 프로젝트에서 네트워크 프로그래밍을 단순화하기 위해 라이브러리를 작성하고 있습니다. 앞으로도 거의 모든 프로젝트에서이 기능을 사용할 수 있기 때문에 강력하고 효율적 이길 원합니다. (BTW 서버와 클라이언트 둘 다 내 라이브러리를 사용하므로 내 질문에 프로토콜을 가정하지 않습니다) 나는 31 바이트의 버퍼와 하나의 센티널을 사용하는 네트워크 스트림에서 문자열을 수신하는 함수를 작성하고 있습니다. 센티널 값은 EOF가있는 경우 어떤 바이트인지 나타냅니다. 여기에 귀하의 사용 또는 조사에 대한 내 코드 ...C# Network Stream getString 메서드

public string getString() 
    { 
     string returnme = ""; 
     while (true) 
     { 
      int[] buff = new int[32]; 
      for (int i = 0; i < 32; i++) 
      { 
       buff[i] = ns.ReadByte(); 
      } 
      if (buff[31] > 31) { /*throw some error*/} 
      for (int i = 0; i < buff[31]; i++) 
      { 
       returnme += (char)buff[i]; 
      } 
      if (buff[31] != 31) 
      { 
       break; 
      } 
     } 
     return returnme; 
    } 

편집의 :가요 (효율적이고 실용적인 등) 최고의 내가 뭘하는지 수행하는이.

+0

질문이 없으므로 자세한 정보를 제공해주십시오. – user854301

+1

바이트가 아닌 31 개의 정수를 사용하고 있습니다. 또한 .. 귀하의 질문은 무엇입니까? –

답변

3

내가하는 일을 수행하는 데 가장 효율적 (실용적인 방법 등)인가요?

번호는 첫째, 당신은 255 코드 포인트 범위의 문자에 자신을 제한하고, 그 는 둘째 충분하고,되지 않습니다 : 문자열을 직렬화하는 것은 해결 된 문제입니다. Encoding (일반적으로 UTF-8) 만 사용하면됩니다. 네트워크 스트림의 일부로 이것은 아마도 "길이를 encode하고, 데이터를 인코딩하고" "길이를 읽고, 많은 양의 데이터를 버퍼링하고, 데이터를 디코딩"합니다. 또 다른 참고 사항 : ReadByte()이 음수 값을 반환하면 EOF 시나리오를 올바르게 처리하지 못합니다.

작은 결과로 string에 루프를 추가하는 것은 결코 좋은 생각이 아닙니다. 의 경우 이렇게하면 StringBuilder을 사용하십시오. 그러나 이렇게하지 마십시오. 당신이 보내는 경우 : 내가 말할 것이다, 최종 참고로

// read the length   
int bytes = (int)ReadUInt32Variant(false); 
if (bytes == 0) return ""; 

// buffer that much data 
if (available < bytes) Ensure(bytes, true); 

// read the string 
string s = encoding.GetString(ioBuffer, ioIndex, bytes); 

// update the internal buffer data 
available -= bytes; 
position += bytes; 
ioIndex += bytes; 
return s; 

: 내 코드 (여기 protobuf - 그물, 단순화 조금에서 내 실제 문자열 읽는 코드의 헤이, whadya 알고) 더 같은 것 구조화 된 메시지를 전문적으로 다루는 미리 롤링 된 직렬화 API 사용에 대해 진지하게 고려해야합니다.

var msg = new MyMessage { Name = "abc", Value = 123, IsMagic = true }; 
Serializer.SerializeWithLengthPrefix(networkStream, msg); 

다른 끝 : 수행

var msg = Serializer.DeserializeWithLengthPrefix<MyMessage>(networkStream); 
Console.WriteLine(msg.Name); // etc 

작업 예를 들어, 당신은 단지 뭔가를 할 수 있습니다.

+0

저는 초보자입니다. 대답의 코멘트를 덜 추상적으로 설명하기 위해 편집 할 수 있습니까? – David

+0

@ user1580785 어떤 비트가 추상적입니까? 행복하게 도울 수 있지만 더 분명해야합니다. 정보의 경우 0-255 한도의 문제는 EOF를 처리하지 않고 문자열 추가는 추상적 인 것이 아니라 진짜 문제입니다. –

+0

코드를 다시 읽은 후 (비 직렬화) 몇 번 클릭하면 모두 "확인"및 "내부 버퍼 데이터 업데이트"가 제외됩니다. 이 데이터를 이미 버퍼에 넣은 것 같아요하지만이 구현하는 방법을 생각해내는 데 어려움을 겪고 있습니다. 도움이 될만한 코드를 추가 할 수 있다면 – David

0

나는 더 나은 성능을 위해 고정 크기의 StringBuilder 객체를 사용해야한다고 생각합니다.

+0

왜 고정 크기입니까? –