2015-06-22 74 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

相关问题