2017-11-28 1 views
0

소켓 클라이언트/서버를 사용하여 문제가 발생했습니다. 클라이언트 측에서닫는 소켓 원인 TIME_WAIT 보류 중 상태

private static void Send(Socket handler, String data) 
{ 
    try 
    { 
     // Convert the string data to byte data using ASCII encoding. 
     byte[] byteData = Encoding.ASCII.GetBytes(data); 

     // Begin sending the data to the remote device. 
     handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler); 
    } 
    catch { } 
} 

private static void SendCallback(IAsyncResult ar) 
{ 
    try 
    { 
     // Retrieve the socket from the state object. 
     Socket handler = (Socket)ar.AsyncState; 

     // Complete sending the data to the remote device. 
     int bytesSent = handler.EndSend(ar); 
     Console.WriteLine("Sent {0} bytes to client.", bytesSent); 

     handler.Shutdown(SocketShutdown.Both); 
     //handler.Dispose(); 
     handler.Close(); 



    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e.ToString()); 
    } 
} 

, 나는 가까운 소켓 함수를 호출 내가 서버에서 대답을 읽은 후 : 내가 응답을 보낸 후 내 소켓 흐름에서

, 나는 서버 측에 닫습니다

var cc = new AsynchronousClient("192.168.1.201", 11001); 
var er = cc.echo(); 
cc.closeConn(); 

public void closeConn(){ 
    sc.Close(); 
} 

public void Close() 
{ 
    if (socket != null && IsConnected) 
    { 
     OnClosed(this, EventArgs.Empty); 
     IsConnected = false; 

     socket.Close(); 
     socket = null; 
    } 
} 

TCPView를 사용하여 서버 측과 클라이언트 측에서 호출이 호출 된 후 포트가 TIME_WAIT 상태임을 알 수 있습니다. Dispose, Disconnect 및 다른 빠른 솔루션과 같은 방법을 사용하는 것과 같은 다른 솔루션을 사용해 보았지만 아무 것도 연결을 닫도록 강제하지 않고 통신이 끝날 때 포트를 해제하는 것처럼 보이지 않습니다.

이 이미지를 보면 TIME_WAIT이 (가) 소켓의 실제 닫기 전 마지막 상태임을 알 수 있습니다.

예를 들어 서버 측 연결 만 닫으려고했습니다. 내가 얻는 것은 CLOSE_WAIT 상태에서 차단 된 클라이언트와 FIN_WAIT2 상태에서 서버입니다. TIME_WAIT 전 단계입니다.

나는 어떤 식 으로든 TIME_WAIT에서 CLOSED (으)로 전달할 마지막 ACK를 보내야한다고 생각합니다. 내 목표에 어떻게 도달 할 수 있습니까?

enter image description here

UPDATE :

내가 내 서버 측에서이 시도는 :

var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

// Bind the socket to the local endpoint and listen for incoming connections. 
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
listener.Bind(localEndPoint); 
listener.Listen(100); 
+1

목표는 무엇입니까? 'TIME_WAIT'을 피하십시오? 아니, 할 수 없어. 효과를 최소화하려면'so_reuseaddr'을 사용하십시오. –

+0

@ZangMingJie 네, 저의 목표는 TIME_WAIT를 피합니다 .. 할 수 없습니까? 업데이트를 보면서 reuseaddress 옵션을 시도했지만 변경 사항을 알지 못했습니다. 어쩌면 내가 잘못된 방향으로 설정 했을까? –

+0

이 (가) 'TIME_WAIT'이면 어떤 문제가 발생합니까? 그렇지 않다면, 누가 걱정하는지. 당신은 그것을 피할 수없고 무시하십시오. –

답변

0

이 솔루션은 윈도우 API를 사용합니다. 여기

코드 :

[DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
public static extern int closesocket(IntPtr s); 

그리고 통화가 나는 둘, 하나 개의 측면이 전화

closesocket(socket.Handle); 

입니다. TCPView를 사용하여 오랫동안 분석 한 결과 예상대로 작동한다고 말할 수 있습니다.