如何使用.Net套接字重用TCP端点地址

时间:2013-03-06 08:17:56

标签: c# .net sockets tcp

我有一些客户端 - 服务器套接字代码,我希望能够构建和(重新)定期连接相同的端点地址: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在数据报套接字上发送时)   电话)没有提供地址“

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

  1. 启动服务器并等待接受连接
  2. 启动客户端并连接到服务器
  3. 接受服务器上的客户端连接
  4. 向客户发送消息
  5. 必要时重复
  6. 我该怎么做?

    提前谢谢!

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

2 个答案:

答案 0 :(得分:3)

您有两个问题:

1)你关闭了听众。把它打开吧。

2)你在错误的套接字上设置ReuseAddress太晚了。 之前将其设置在侦听套接字bind(因为在您使用该地址时就是这样)。

在套接字上设置ReuseAddress,您不会bind做任何事情。您可以从客户端删除它。

答案 1 :(得分:0)

我尝试了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();
}

谢谢,全部!