2010-08-17 4 views
1

인사말, C#에서 사용자 지정 텔넷 클라이언트가 있습니다. IMAP 서버와 통신하는 데 사용하고 있습니다. 쓰기 명령으로 작동 한 다음 응답을받습니다. 테스트 코드 : 코드 위의 호출에서스트림에 읽기/쓰기를 동기화하는 방법은 무엇입니까?

  Telnet tc = new Telnet(); 
      // setup server credentials 
      const string server = "pop.nexlink.net"; 
      const int port = 140; 
      const int timeout = 70; 
      // establish server connection 
      tc.Setup(server, port, timeout); 
      // test initial server response 
      Console.WriteLine(tc.output); 

      // set-up a few commands to send 
      var array = new[] { "USER [email protected]", "PASS password", "QUIT" }; 

      // while connected to server 
      if (tc.IsConnected) 
      { 
       foreach (string str in array) 
       { 
        // Show command on console 
        Console.WriteLine(str); 
        // Write to Stream 
        tc.WriteLine(str); 
        // Read from Stream 
        tc.Read(); 
        // Test the Stream output 
        Console.Write(tc.output); 
       } 


      } 
      // close connection 
      tc.Disconnect(); 

출력은 다음과 같습니다 Atmail의 POP3 서버에

  1. 사용자 [email protected]
  2. + OK 오신 것을 환영합니다 - 사용자 @ 도메인으로 로그인합니다.
  3. + 비밀번호가 필요합니다.
  4. PASS 암호
  5. 는 + OK
  6. 가 로그인 종료합니다.
  7. + OK 안녕.

이것은 단순한 예이지만 경쟁 조건의 문제를 보여줍니다. nr.6 라인 출력은 nr. 5

Q : 어떻게 처리합니까?

+0

잘하고있는 것 같습니다. 서버는 사용자 로그인을 마치기 전에 종료 메시지를 수신합니다. –

+0

가능합니다. 응답은 다소 임의적입니다. 연결 속도, 서버 응답 시간, 반환 할 데이터 양에 따라 다릅니다. 더 커다란 흐름을 요구하는 명령이 더 많아지면 정말 지저분 해집니다. 일반적으로 읽기는 쓰기보다 훨씬 느립니다. – asyncpro

답변

0

이전에 직접 내 텔넷 클라이언트를 작성했습니다. 명령을 처리하는 방법은 각 명령에 대한 입력과 예상 응답 (예상했던 회신 중 일부 + OK)으로 각 명령의 흐름을 작성하는 것입니다. 이렇게하면 명령을 보내고 응답을 기다릴 수 있습니다. 응답이 수신되지 않거나 일치하지 않으면 예외를 throw합니다.

텔넷은 명령별로 많은 응답 (공백, 페이지 변경, 로그온 흐름 등)을 보낼 수 있습니다. 따라서 예상되는 응답을 기다리는 것이 필요합니다.

+0

여기서는 작동하지 않습니다. 이 프로그램이 작동해야하는 서버가 많이 있습니다 (저는 ISP 사업에 종사하고 있습니다). 보다 일반적인 해결책을 환영합니다. 멀티 스레딩과 리소스 잠그기에 대해 생각하고 있었지만 그렇게하는 방법은 모릅니다. – asyncpro

+0

이 방법으로는 다중 서버 환경이 작동하지 않습니다. 설명하십시오 ... 한 번에 하나의 텔넷 인스턴스에만 연결됩니다. 권리? 필요한 모든 명령을 캡슐화 한 후 Telnet 정면을 WCF 서비스로 공개하고 Telenet 서버에 대한 연결 풀을 관리합니다. – CkH

1

첫째, IMAP 메일 서버는 텔넷을 사용하지 않습니다. 텔넷은 TCP 위에있는 프로토콜입니다. RFC 854을 참조하십시오. 그러나 텔넷 클라이언트의 장점은 텔넷이 원시 TCP 소켓의 맨 위에있는 아주 최소한의 프로토콜이기 때문에 TCP (POP3, IMAP 등) 위에 텍스트 명령/응답 스타일 프로토콜을 사용하는 많은 서비스에 연결하여 상호 작용할 수 있다는 것입니다. SMTP, HTTP 등).

궁극적으로 "오프라인 IMAP 클라이언트"를 사용해야합니다. 임의의 Google 검색을 수행하면 this one으로 연결됩니다. 나는 그것이 좋은 것인지 전혀 모른다. 그러나 그것은 당신의 일부 위에서 빠른 승리를 가져올지도 모른다.

그러나 TCP/IP 네트워킹을 올바르게 수행하는 방법을 배우려면 양방향 IO에 대한 몇 가지 기본 사항을 알아야합니다.

여기에서 겪고있는 것은 꽤 정상입니다. TCP 소켓에는 두 개의 채널이 있습니다. 읽기 용으로 하나, 쓰기 용으로 하나. 이러한 채널은 독립적이며 잠재적으로 버퍼링됩니다.

버퍼링이란 클라이언트 코드에서 보내는 소켓에 일부 데이터 (줄 또는 기타)를 썼다 고해서 버퍼가 다른 쪽에서 수신되었음을 의미하지는 않습니다.

따라서 쓰기 후에 즉시 차단하면 명령이 전송되지 않고 영구히 읽히지 않을 수도 있습니다.

또한 OS와 대역폭만큼 빠르게 보내는 소켓에 명령을 쓸 수 있습니다. 서버가 처리 할 때마다 응답이 돌아옵니다. 곧 있을지도 모르는 일일 수도 있습니다.매우 성격 상 소켓 프로그래밍은 비동기식이며 실패하기 쉽습니다 (신뢰할 수없는 네트워크를 통해 원격 시스템을 다루고 있습니다).

비동기 양방향 IO를 처리하는 일반적인 방법은 두 개의 스레드를 사용하는 것입니다. 하나는 읽기 용이고 다른 하나는 쓰기 용입니다. "재미"는 두 스레드 간의 응답 & 요청의 "채팅"을 조정해야 할 때 시작됩니다. AutoResetEvent 및 ManualResetEvent와 같은 스레딩 프리미티브가 여기에 도움이 될 수 있습니다. C# Reactive Extensions을 보는 것이 가장 효과적 일지 모르지만 작업을 훨씬 간단하게 만들 수 있습니다.

전반적으로 나는 reading up on the topic을 제안합니다. 좋은 오류가없는 네트워크 코드를 작성하는 것은 SMTP & POP3와 같은 "단순한"프로토콜에 대해서조차도 중요하지 않습니다.

솔루션에 C#을 사용하지 않고 단순한 Telnet 스타일 서비스 상호 작용을 자동화하려는 경우 Linux/Unix 유틸리티 expect을 살펴 봐야 많은 시간을 절약 할 수 있습니다.

+0

감사합니다. 위의 내용을 모두 확실히 확인하겠습니다. – asyncpro

관련 문제