2015-06-22 73 views
-1

我在C#中的.Net套接字中遇到了一些問題。 我編寫了一個客戶端和一個使用TCP的服務器。C#.Net套接字服務器客戶端

當客戶端打開時,它向服務器發送握手。服務器回答它的狀態(客戶端,客戶端,...)。之後,應用程序發送getdata請求,放棄連接並監聽服務器的「響應」。現在,服務器建立到客戶端的連接併發送客戶端需要的所有數據。

的代碼和其他一切工作,但問題:

在我們公司TESTSERVER它工作正常,直播服務器只握手工作在。之後,客戶端不會再收到任何數據。 Servepplication在兩臺服務器上都是一樣的。

我認爲這個問題是由一些防火牆引起的(服務器想建立到客戶端的tcp連接 - >不好),但是系統管理員說沒有防火牆可以阻止這個問題。

現在我正在尋找一種不需要太多時間和代碼更改的('便宜')解決方案。如果有人知道如何從理論上解決這個問題,那就太好了。

BTW:除了運行服務器應用程序,我不允許在活服務器上執行任何操作。我無法在此服務器上進行調試。

我無法發佈我的所有代碼,但如果您需要查看它的特定部分,請索取。

---編輯---

客戶端服務器通信

1)客戶端啓動
客戶端發送握手(新的TCP連接)
2)服務器驗證握手,並節省IP
服務器迴應它的客戶端狀態(相同的TCP連接)
3)客戶端確認此響應並放棄此連接
客戶端發送getdata-request(新的tcp連接)
客戶端放棄該TCP連接,過於
4)服務器接收的GetData請求並收集在主數據庫
5)客戶端接收所有需要的數據
服務器所有所收集的數據發送到客戶端(多個TCP連接)數據並顯示它在它的GUI

這是最主要的部分我的代碼做(多個TCP連接和數據的順序是由與插座的AutoResetEvents並計數派工作保持)。這是迄今爲止不是最好的,但我認爲這是我寫的。第一步,第二步和第三步按預期工作。數據的處理也可以正常工作。 我忘記提及的另一件事是解決方案使用兩個端口'16777'和'16778'。一個收/聽,一個發送。 我的代碼基於異步serverclient的MSDN示例。

發送握手(和的GetData請求)

public void BeginSend(String data) 
    { 
     try 
     { 
      StateObject state = new StateObject(); 
      state.workSocket = sender; 

      byte[] byteData = Encoding.UTF8.GetBytes(data); 

      sender.BeginSend(byteData, 0, byteData.Length, 0, 
       new AsyncCallback((IAsyncResult e) => 
       { 
        Socket socket = (Socket)e.AsyncState; 
        SocketBase.StateObject stateObject = new SocketBase.StateObject(); 
        stateObject.workSocket = socket; 
        socket.BeginReceive(stateObject.buffer, 0, 256, SocketFlags.None, new AsyncCallback(this.ReadCallback), (object)stateObject); 

       }), sender); 

      sender = RetrieveSocket(); //Socketreset 

      Thread.Sleep(100); 
     } 
     catch /*(Exception e)*/ 
     { 
      //-- 
     } 
    } 

服務器監聽

public void StartListening() 
    { 
     listener = new Socket(AddressFamily.InterNetwork, 
      SocketType.Stream, ProtocolType.Tcp); 

     // Bind the socket to the local endpoint and listen for incoming connections. 
     try 
     { 
      listener.Bind(localEndPoint); 
      listener.Listen(System.Int32.MaxValue); 

      while (true) 
      { 
       // Set the event to nonsignaled state. 
       allDone.Reset(); 

       // Start an asynchronous socket to listen for connections. 
       listener.BeginAccept(
        new AsyncCallback(AcceptCallback), 
        listener); 

       // Wait until a connection is made before continuing. 
       allDone.WaitOne(); 
      } 

     } 
     catch (Exception e) 
     { 
      //-- 
     } 
    } 

    public void AcceptCallback(...); 
    public void ReadCallback(...); 

插槽發送

private void Send(Socket handler, String data) 
    { 
     Socket t = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint).Address); 
     // Convert the string data to byte data using ASCII encoding. 
     byte[] byteData = Encoding.UTF8.GetBytes(data); 

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

套接字發送的所有數據部分(答案的GetData請求| socToHandle應該是getdata請求的上一個連接的套接字)

private void SendAllData(Socket socToHandle, string PakContent) 
    { 
     #region IsThereADatetime? //Resolve a given datetime 

     #region GiveClientNumberOfPackets //Send the client info about how much he has to receive (See line below) 

      Send(socToHandle, "ALERT#TASKCOUNT;OPT-" + GetBestDate(dateStart) + EndSocket); 


     #region #SendResouces 
     #region #SendGroups 
     #region #SendTasks 
    } 

翻翻我的舊代碼,我有一個想法=>

我能否通過改變發送一切通過相同的連接:

的Socket T = RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint) 。地址);

(這將創建一個新的連接)的東西,使用相同的連接? 如果這可行,我該怎麼做? 客戶端的偵聽器部分仍然會收到單個數據包嗎?

+1

假設系統管理員在於。 嘗試使用https://technet.microsoft.com/en-us/sysinternals/jj729731.aspx端口上運行服務器和測試連接。上傳試圖ping您的客戶端IP的代碼版本。 也雙方都應該經常測試防火牆/連接問題並記錄它們。 – Nahum

+0

您不必向我們展示「我的所有代碼」 - 事實上,這樣做會適得其反。 *會有用的是你創建一個[MCVE](http://stackoverflow.com/help/mcve)。 –

+0

TCP實現中的常見錯誤與處理接收到的流有關。接收過程必須考慮到可能在不同的塊中接收到發送請求。需要使用長度值方法或使用分隔符來封裝發送數據,例如, STX和ETX。 – Graffito

回答

1

服務器和他們的環境配置爲正確處理傳入的請求。客戶端通常位於路由器後面,默認情況下,它們無法接收來自外部網絡的傳入連接(這是件好事)。

要啓用傳入的連接,則可以將路由器配置爲某個端口號的所有請求轉發到您的計算機。但是,您的網絡上沒有其他人能夠運行客戶端。

這就是爲什麼在典型的多個客戶端 - 單個服務器環境中,客戶端進行所有連接,並且只有服務器需要對網絡環境進行任何更改。

我不知道你爲什麼選擇從服務器端連接到客戶端,但我會強烈反對這項建議 - 使用該機制可能變成是到底很貴任何廉價的解決方案。

+0

感謝您的建議,我一定會在將來做到這一點,但我現在沒有時間重寫所有的代碼。在任何客戶端和服務器之間都沒有路由器,只有第2層交換機。 – ShinuSha

相關問題