首页 文章

C#.Net套接字服务器客户端

提问于
浏览
-1

我对C#中的.Net套接字有一点问题 . 我编写了一个客户端和一个使用TCP的服务器 .

当客户端打开时,它会向服务器发送握手 . 服务器用它的状态回答(clientexists,clientaccepted,...) . 之后,应用程序发送getdata-request,放弃连接并侦听服务器的“响应” . 现在,服务器构建与客户端的连接,并发送客户端所需的所有数据 .

代码和其他一切都有效,但问题是:

在我们公司的testserver上工作正常,在实时服务器上只有握手才能工作 . 在它之后,客户端不再接收任何数据 . 两个服务器上的服务应用程序是相同的 .

我认为问题是由一些防火墙引起的(服务器想要 Build 到客户端的tcp连接 - >不好),但是系统管理员说没有可以阻止它的防火墙 .

现在我正在寻找一种(“廉价”)解决方案,它不需要太多时间和代码更改 . 如果有人知道如何在理论上解决这个问题,那就太好了 .

顺便说一句:除了运行serverapplication之外,我不允许在实时服务器上做任何事情 . 我无法在此服务器上进行调试 .

我无法发布所有代码,但如果您需要查看其中的特定部分,请提出要求 .

  • -编辑 - -

客户端 - 服务器通信

1)客户端启动
客户端发送握手(新的TCP连接)
2)服务器验证握手并保存IP
服务器响应它的客户端状态(相同的tcp连接)
3)客户确认此响应并放弃此连接
客户端发送getdata-request(新的tcp连接)
客户端也放弃了这个tcp连接
4)服务器接收getdata-request并在主数据库中收集所需的数据
服务器将所有收集的数据发送到客户端(多个tcp连接)
5)客户端接收所有数据并将其显示在其GUI中(多个tcp连接,并通过使用AutoResetEvents和Counts of socket发送来保存数据的顺序)

这是我的代码的主要部分 . 它's by far not the best but it was for me as I wrote it I guess. Step one, two and three work as intended. The processing of the data works fine, too. Another thing i forgot to mention is that the solution uses two Ports ' 16777 ' and ' 16778' . 一个接收/收听和一个发送 . 我的代码基于异步serverclient的MSDN示例 .

发送握手(和getdata-request)

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-request | socToHandle应该是getdata-request先前连接的套接字)

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).Address);

(创建新连接)到使用相同连接的东西?如果这样可行,我该怎么做?并且客户端的侦听器部分是否仍然会收到单个数据包?

1 回答

  • 1

    服务器及其环境配置为正确处理传入请求 . 客户端通常位于路由器后面,默认情况下,它们无法接收来自网络外部的传入连接(这是一件好事) .

    要启用传入连接,您可以将路由器配置为将特定端口号的所有请求转发到您的计算机 . 但是,您的网络上没有其他人能够运行客户端 .

    这就是为什么在典型的多客户端 - 单服务器环境中,客户端进行所有连接,并且只有服务器需要对网络环境进行任何更改 .

    我不知道你为什么选择从服务器端连接到客户端,但我强烈建议不要这样做 - 任何使用这种机制的廉价解决方案最终可能会变得非常昂贵 .

相关问题