c# - C# 在同一个套接字上发送+接收数据

标签 c# .net sockets

我正在尝试使用套接字(System.Net.Socket,甚至尝试过 TcpListener/Client/Etc.)来在等待或已经发送数据时监听数据。

我已完成以下操作:

    public byte[] bytesIn;
    public byte[] bytesOut;
    public Socket transmitter;
    public Socket receiver;

    public Comlink(String ipAddress, int portNum) 
    {

        try
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress), 11000);

            transmitter = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            transmitter.Listen(10);

            receiver = transmitter.Accept();
            receiver.Receive(bytesIn);

            try
            {
                transmitter.Connect(remoteEP);
                this.bytesOut = Encoding.ASCII.GetBytes("<SYNCUP>");
                int bytesSent = transmitter.Send(this.bytesOut);
                this.connected = true;
            }
        }  // (Omitted my exception handling.)
    }

Receive() 函数:

this.bytesIn = new byte[1024];
Socket receiver = transmitter.Accept();
int bytesReceived = receiver.Receive(this.bytesIn);

绑定(bind)它的代码:

while(comlink.connected)
{
    comlink.Receive();
    handlePacket(comlink.bytesIn);
}

我只是不完全确定我是否使用了正确的流程来接收数据,因为这一直是 .NET 的提示。我需要在数据传入时对其进行处理。

有点像双向街道:数据可以自由进入(程序不必返回到 Receive() 并等待数据),它会被处理。数据也可以自由地从客户端移动到服务器。我知道 TCP 套接字是双向的,但我需要改进此类,以便我可以享受自由、开放道路的全部好处。

最佳答案

仅您显示的代码至少有两处错误。首先,您的套接字应该用于监听或连接到远程套接字,但不能同时用于两者。坦率地说,我很惊讶当代码在进入监听模式后尝试调用 Connect() 时,.NET 没有抛出异常。

其次,您只需要接受一次连接。在每次调用 Receive() 之前接受是错误的,并且会导致您的代码仅从与其连接的每个套接字接收第一个缓冲区的数据。

一般来说,基于 Socket 的实现需要一个“服务器”和一个“客户端”。请注意,一旦建立了连接,角色就不需要保持如此牢固的建立状态。但至关重要的是,他们还处于起步阶段。

服务器将创建一个新的“监听”套接字。使用此套接字,它将“接受”来自客户端的连接请求,该过程将创建一个实际用于通信的套接字。

我重申:服务器的原始套接字从未用于通过连接进行实际通信。它只是用于创建连接的套接字。

客户端将创建一个套接字。使用此套接字,它将尝试“连接”到服务器的套接字。一旦建立连接,同一个套接字就会用于实际通信。

正如您所注意到的,TCP 连接是双向的。因此,一旦建立连接,服务器和客户端都可以使用各自的单个套接字进行连接来发送和接收数据。当然,请注意,在单线程代码中,您不能同时执行这两项操作。因此,要么您的高级协议(protocol)需要是调用和响应风格的协议(protocol),其中每一端都准确地知道何时需要发送或接收数据,并且永远不需要同时执行这两项操作,或者您需要使用.NET 为套接字提供的异步 API 之一,以便您可以同时处理发送和接收。

MSDN 有相当不错的 Socket 编程示例。您应该从这里开始。

很久以前(无论如何在互联网年代:)),我写了一系列博客文章来尝试帮助人们开始 .NET Socket 编程。这是我最后有时间写的为数不多的事情之一;如果它对您有帮助,您可以考虑检查一下: http://blogs.msmvps.com/duniho/2008/08/19/basic-network-programming-in-net/

关于c# - C# 在同一个套接字上发送+接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26374478/

相关文章:

javascript - Plupload block 大小将文件重命名为 Blob

c# - 是否应该始终在 .NET 中编写 null-proof 扩展方法?

.net - 从 UserControl 的子控件传递事件 - 最直接的方法?

.net - 防止方法出现在 Stack Traces 中

php - Php和Redis之间的高流量连接

c++ - pselect 阻塞,即使数据可用于在套接字上读取

c# - 在 C# 中从 Window 服务启动应用程序

c# - 使用 C# 下载包含密码和用户名的文件

.net - 当我的大型 ASP.NET 站点更新时,IIS 必须重新编译其中的很多内容。有没有办法显着减少我的编译时间?

wcf - ValidateUriRoute-这是什么?为什么它中止了我的套接字?