【问题标题】:How do I reuse a TCP endpoint address with .Net sockets如何使用 .Net 套接字重用 TCP 端点地址
【发布时间】:2013-03-06 08:17:55
【问题描述】:

我有一些客户端-服务器套接字代码,我希望能够构造和(重新)定期连接到相同的端点地址:localhost:17999

这里是服务器:

// Listen for a connection:
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 17999);             
Socket listener = new Socket(IPAddress.Loopback.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
listener.Bind(localEndPoint);
listener.Listen(1);

// Accept the connection and send a message:
Socket handler = listener.Accept();
byte[] bytes = new byte[1024];
bytes = Encoding.ASCII.GetBytes("The Message...");                 
handler.Send(bytes);

// Clean up
handler.Shutdown(SocketShutdown.Both);
handler.Close();
handler.Dispose();

listener.Shutdown(SocketShutdown.Both);
listener.Close();
listener.Dispose();

这里是客户端:

byte[] bytes = new byte[1024];
Socket receiver = new Socket(IPAddress.Loopback.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
receiver.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
receiver.Connect(new IPEndPoint(IPAddress.Loopback, 17999));

int num_bytes_received = receiver.Receive(bytes);
string result = Encoding.ASCII.GetString(bytes, 0, num_bytes_received);

receiver.Shutdown(SocketShutdown.Both);
receiver.Close();
receiver.Dispose();

当我第一次创建客户端和服务器时,它工作正常。但是,当我再次创建它时,出现错误:

"发送或接收数据的请求被拒绝,因为套接字是 未连接并且(当使用 sendto 在数据报套接字上发送时 call) 没有提供地址"

我希望能够在需要时按照以下事件顺序任意启动此机制:

  1. 启动服务器并等待接受连接
  2. 启动客户端并连接到服务器
  3. 在服务器上接受客户端连接
  4. 向客户端发送消息
  5. 必要时重复

我该怎么做?

提前致谢!

编辑:每次我构建客户端和服务器对象时,它都来自不同的进程。

【问题讨论】:

    标签: c# .net sockets tcp


    【解决方案1】:

    你有两个问题:

    1) 你正在关闭监听器。让它保持打开状态。

    2) 您在错误的套接字上设置了ReuseAddress,而且为时已晚。 在调用bind 之前将它设置在监听套接字上(因为那是你使用地址的时候)。

    在您不会使用bind 的套接字上设置ReuseAddress 不会做任何事情。您可以将其从客户端中删除。

    【讨论】:

    • (1) 每个侦听器都位于不同的进程中,因此如果另一个进程要尝试在同一端点地址上建立连接,我应该进行清理,并且 (2) 尝试过,但没有t 有任何区别(上面编辑过)
    • 客户端或服务器是否收到错误消息?它究竟是什么时候发生的? (并确保在客户端之前启动服务器,否则这是预期行为。)
    • 监听器应该只接受传入的连接并产生一个处理客户端的新线程。您经常在此类程序中看到while (Running) { var socket = listener.Accept(); // ... }
    • @David,错误发生在服务器的 listener.Accept();第二次运行客户端连接到同一个端点地址
    • @Gene,这将如何解决这个问题?
    【解决方案2】:

    我尝试了 Gene 的建议,它似乎有效:

    // Listen for a connection:     
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Loopback, 17999);
    using (Socket listener = new Socket(IPAddress.Loopback.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
    {
    
        listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        listener.Bind(localEndPoint);
        listener.Listen(1);
    
        Thread t = new Thread(() =>
        {
            // Accept the connection and send a message:
            using (Socket handler = listener.Accept())
            {
                byte[] bytes = new byte[1024];
                bytes = Encoding.ASCII.GetBytes("The Message...");
                handler.Send(bytes);
            }
        });
        t.Start();
        t.Join();
    }
    

    谢谢大家!

    【讨论】:

      猜你喜欢
      • 2015-02-16
      • 1970-01-01
      • 2011-10-01
      • 2010-12-26
      • 1970-01-01
      • 2017-12-12
      • 2012-08-25
      • 1970-01-01
      • 2015-07-25
      相关资源
      最近更新 更多