我正在尝试使用套接字(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);
绑定它的代码:
while(comlink.connected)
{
comlink.Receive();
handlePacket(comlink.bytesIn);
}
我只是不完全确定我是否使用正确的流程来接收数据,因为这一直是.NET的抱怨。我需要处理数据。
类似于双向的道路:数据可以自由进入(程序不必返回到Receive()并等待数据),它会得到处理。数据也可以从客户端自由移动到服务器。我知道TCP套接字是双向的,但我需要改进这个类,以便我可以享受自由开放的道路带来的全部好处。
答案 0 :(得分:1)
您展示的代码至少有两个问题。首先,您的套接字应该用于侦听或连接到远程套接字,但不能同时用于两者。坦率地说,当代码在已经进入侦听模式后尝试调用Connect()时,我很惊讶.NET不会抛出异常。
其次,您只需要接受一次连接。在每次调用Receive()之前接受是错误的,并且会导致您的代码仅从连接到它的每个套接字接收第一个缓冲区的数据。
通常,基于Socket的实现需要一个&#34;服务器&#34;和一个&#34;客户&#34;。请注意,一旦建立连接,角色就不需要保持如此牢固的建立。但它们起初是至关重要的。
服务器将创建一个新的&#34; listen&#34;插座。有了这个插座,它将接受&#34;接受&#34;来自客户端的连接请求,这个进程将创建一个实际用于通信的 new 套接字。
我重申:服务器的原始套接字从不用于通过连接进行实际通信。它只是用于创建连接的套接字。
客户端将创建一个套接字。使用此插座,它将尝试连接&#34;到服务器的套接字。建立连接后,相同的套接字将用于实际通信。
如您所知,TCP连接是双向的。因此,一旦建立连接,服务器和客户端就可以使用它们的单个套接字来连接发送和接收数据。当然,请注意,在单线程代码中,您无法同时执行这两项操作。因此,您的高级协议需要是一个调用和响应式协议,其中每个端都准确地知道何时需要发送或接收数据,并且它永远不需要同时执行这两个,或者您需要使用.NET为套接字提供的异步API之一,以便您可以同时处理发送和接收。
MSDN具有相当不错的Socket编程示例。你应该从那里开始。
很久以前(无论如何在互联网年代:)),我写了一系列博客文章,试图帮助人们开始使用.NET Socket编程。这是我找到时间写作的少数几件事之一;如果它对您有帮助,您可以考虑检查它: http://blogs.msmvps.com/duniho/2008/08/19/basic-network-programming-in-net/