简体   繁体   English

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

[英]How do I reuse a TCP endpoint address with .Net sockets

I have some client-server socket code that I want to be able to construct and (re)connect to periodically the same endpoint address: localhost:17999 我有一些客户端 - 服务器套接字代码,我希望能够构建和(重新)连接到周期性相同的端点地址: localhost:17999

Here is the server: 这是服务器:

// 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();

And here is the client: 这是客户:

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();

When I create the client and server for the first time, it works fine. 当我第一次创建客户端和服务器时,它工作正常。 However when I create it again, I get an error: 但是,当我再次创建它时,我收到一个错误:

"A request to send or receive data was disallowed because the socket is not conne cted and (when sending on a datagram socket using a sendto call) no address was supplied" “不允许发送或接收数据的请求,因为没有连接套接字,并且(当使用sendto调用在数据报套接字上发送时)没有提供地址”

I would like to be able to spin up this mechanism arbitrarily whenever I need to with the following order of events: 我希望能够在需要时遵循以下事件顺序任意改变这种机制:

  1. Launch the server and wait to accept a connection 启动服务器并等待接受连接
  2. Launch the client and connect to the server 启动客户端并连接到服务器
  3. Accept the client connection at the server 接受服务器上的客户端连接
  4. Send a message to the client 向客户发送消息
  5. Repeat when necessary 必要时重复

How can I do this? 我怎样才能做到这一点?

Thx in Advance! Thx提前!

EDIT: Each time I build the client and server objects it is from a different process. 编辑:每次我构建客户端和服务器对象时,它来自不同的进程。

You have two issues: 你有两个问题:

1) You're closing the listener. 1)你正在关闭听众。 Just leave it open. 把它打开吧。

2) You're setting ReuseAddress on the wrong socket and way too late. 2)你在错误的套接字上设置ReuseAddress并且为时已晚。 Set it on the listening socket before you call bind (since that's when you use the address). 调用bind 之前将它设置在侦听套接字上(因为那是在使用地址时)。

Setting ReuseAddress on a socket you aren't going to bind doesn't do anything. 在不打算bind的套接字上设置ReuseAddress不会执行任何操作。 You can remove that from the client. 您可以从客户端删除它。

I tried what Gene suggested and it seems to work: 我试过基因建议的东西,似乎有效:

// 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();
}

Thanks, all! 谢谢,全部!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM