Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#.Net套接字服务器客户端_C#_.net_Sockets_Tcp - Fatal编程技术网

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

C#.Net套接字服务器客户端,c#,.net,sockets,tcp,C#,.net,Sockets,Tcp,我对C#中的.Net套接字有点问题。 我编写了一个客户端和一个使用TCP的服务器 当客户端打开时,它向服务器发送握手。服务器以其状态(clientexists、clientaccepted,…)进行应答。在此之后,应用程序发送一个getdata请求,放弃连接并侦听服务器的“响应”。现在,服务器与客户端建立连接,并发送客户端需要的所有数据 代码和其他一切都正常,但问题是: 在我们公司的testserver上,它可以正常工作,而在live server上,只有握手可以正常工作。之后,客户端不再接收任

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

当客户端打开时,它向服务器发送握手。服务器以其状态(clientexists、clientaccepted,…)进行应答。在此之后,应用程序发送一个getdata请求,放弃连接并侦听服务器的“响应”。现在,服务器与客户端建立连接,并发送客户端需要的所有数据

代码和其他一切都正常,但问题是:

在我们公司的testserver上,它可以正常工作,而在live server上,只有握手可以正常工作。之后,客户端不再接收任何数据。两台服务器上的服务器应用程序相同

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

现在,我正在寻找一种“便宜”的解决方案,它不需要花费太多的时间和代码更改。如果有人知道如何从理论上解决这个问题,那就太好了

顺便说一句:除了运行服务器应用程序,我不允许在实时服务器上执行任何操作。我无法在此服务器上调试

我不能发布我所有的代码,但如果你需要查看它的特定部分,请索取

---编辑---

客户机-服务器通信

1) 客户端启动
客户端发送握手(新tcp连接)
2) 服务器验证握手并保存IP
服务器以其客户端状态(相同的tcp连接)进行响应
3) 客户端确认此响应并放弃此连接
客户端发送getdata请求(新tcp连接)
客户端也放弃此tcp连接
4) 服务器接收getdata请求并在主数据库中收集所需的数据
服务器将所有收集的数据发送到客户端(多个tcp连接)
5) 客户机接收所有数据并在其GUI中显示(多个tcp连接,通过使用AutoResetEvents和要发送的套接字计数来保持数据的顺序)

这是我的代码的主要部分。这不是最好的,但我想这是我写的。第一步、第二步和第三步按预期进行。数据处理也很好。 我忘记提到的另一件事是,解决方案使用了两个端口“16777”和“16778”。一个接收/收听,一个发送。 我的代码是基于MSDN的异步和

发送握手(和getdata请求)

服务器侦听器

    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请求上一个连接的套接字)

查看我的旧代码,我有一个想法=>

我是否可以通过更改以下内容通过同一连接发送所有内容:

套接字t=RetrieveSocket(((IPEndPoint)handler.RemoteEndPoint.Address)

(创建新连接)到使用相同连接的对象? 如果那样行得通,我怎么做?
客户端的侦听器部分还会接收单个数据包吗?

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

要启用传入连接,可以将路由器配置为将特定端口号的所有请求转发到计算机。不过,您网络上的其他人都无法运行该客户端

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


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

假设系统管理员撒谎。尝试在端口上运行服务器并使用测试连接。上载尝试ping客户端IP的代码版本。另外,双方都应该经常测试防火墙/连接问题并记录它们。你不必向我们展示“我所有的代码”——事实上,这会适得其反。对您有用的是创建一个。TCP实现中的一个常见错误与接收流的处理有关。接收过程必须考虑到发送请求可以在不同的块中接收。您需要使用长度值方法或分隔符(例如STX和ETX)封装发送数据。由于一个较小的网络路由问题,您似乎已经放弃了。只要解决这个问题。显然,代码在您的机器上工作。(不过,结束这个问题,因为这里没有足够的信息来回答。这似乎是一个路由问题,仅此而已。)我很确定您的问题在
ReadCallback
代码中。看起来您忽略了消息帧(您没有发送字符串的长度,也没有终止符;但是如果没有
ReadCallback
code),就无法确定TCP是一个流,而不是一堆消息。Windows处理本地TCP的方式完全不同,这通常会导致应用程序在本地主机上工作(大部分)正常,但在实际网络连接上测试时完全失败。网络交流会带来更多的问题。谢谢你的建议,我以后肯定会这么做,但我现在没有时间重写我所有的代码。任何客户端和服务器之间都没有路由器,只有第2层交换机。
    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);
    }
    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
    }