2015-05-19 106 views
1

所以我有一個客戶端服務器模型,它基於TCPClient流並基於安全目的將其轉換爲SSLStream,但每當客戶端想要向服務器發送新的東西時,它就會打開一個到服務器的新TCP連接,服務器結束連接。我將如何去傾聽來自同一個流的額外請求?不知道如何,這就是爲什麼我最終殺死流。對不起,如果它很混亂,我可以修改,如果不能理解。謝謝!在同一個流上監聽其他請求(TCPClient/SSLStream)?

public void ServerListen() 
{ 
TCPListener Server = new TCPListener(IPAddress.Any, 8001); 
while (true) 
{ 
Server.Start(); 
TCPClient TempClient = Server.AcceptTCPClient(); 
HandleRequest NewRequest = new HandleRequest(TempClient); // Send to a data handler class and open a separate thread to allow for additional clients to connect 
} 
} 


public class HandleRequest 
{ 

TCPClient WorkingClient; 
public HandleRequest(TCPClient TempClient) 
{ 
WorkingClient = TempClient; 
(new Thread(new ThreadStart(DoWork))).Start(); 
} 

public static void DoWork() 
{ 
// Do Something Here With Data From Client 
ProvideResponse(SomeData); 
} 

public static void ProvideResponse(object Data) 
{ 
SSLStream SecureStream = new SSLStream(WorkingClient, false); // Kill inner stream after creating a secure connection 
SecureStream.AuthenticateAsServer(MyCertificate, false, SslProtocols.Tls, true); 
XmlSerializer XS = new XMLSerializer(typeof(someclass)); 
someclass TempObject = new someclass(){ InnerData = Data}; 
if (SecureStream.CanWrite) 
{ 
XS.Serialize(SecureStream, TempObject); 
} 
SecureStream.Close(); 
} 

} 

回答

1

SslStream只是圍繞另一個Stream環繞。如果您撥打AuthenticateAsServer(),另一方應該AuthenticateAsClient(),並從此點開始,您可以通過SSL進行通信。如果任何一方未能調用此方法,則SslStream將引發異常。

如果您關閉與leaveInnerStreamOpen參數設置爲true構建的SslStream,就可以直接通信基礎流過,彷彿從來就沒有一個SslStream(你甚至可以直接發送和從底層流接收到/而SslStream仍然開放)。

在像HTTPS這樣的典型場景中,客戶端和服務器在連接建立後立即啓用SSL,並在連接期間繼續使用SSL。儘管在請求/響應之後關閉了雙方的SslStream,並且爲下一條消息重新創建了一個,但您只需保持客戶端和服務器之間的「ssl狀態」同步即可。

至於您的評論:

一旦TCP連接建立後,您可以發送和,只要雙方保持連接接收數據。例如:

TcpClient client = TcpListener.AcceptTcpClient(); 
NetworkStream stream = client.GetStream(); 
while (true) 
{ 
    int bytes = stream.Read(...); 
    if (bytes == 0) 
    { 
     // other side has disconnected 
     stream.Close(); 
     break; 
    } 

    // add incoming data to buffer, process messages 
    ... 
} 

這就像寫在一張紙上你到彼此的文字與人交談 - 你只是繼續寫在同一張紙上,而你寫的另一邊可以閱讀。

如果您在請求/響應後關閉TcpClient並使用TcpListener.AcceptXxx()打開新的文件,那麼您在每封郵件後都會扔掉每張紙。

如果我是你,我會用這些概念(使用NetworkStream類)沒有SslStream包裝打,直到你覺得你在做正確的事情。可以添加SslStream圖層,而不會對使用NetworkStream的代碼進行任何重大更改。

+0

我其實覺得很有幫助。因此,一旦我設置SSLStream並進行身份驗證,將內部流打開,TCPClient就會使用底層SSL連接?如果是這樣的話,一旦「ProvideResponse」方法完成,我將如何監聽來自TCPClient的額外請求? – CodeJrMasterX

+0

你可以使用'NetworkStream stream = myTCPClient.GetStream()',並且通過該流進行未加密的通信,並從中創建'SslStream'。 –

+0

對不起,也許我錯過了。我可以創建SSLStream(請參閱提供響應),但是一旦我完成並完成了我需要的工作(發送響應),如何通過TCPClient接受進一步的請求?它會像TCPListener' While(WorkingClient.Connect){// do work}'嗎? – CodeJrMasterX