我刚刚开始通过各种 Google 搜索学习套接字,但在弄清楚如何在 C# 中正确使用套接字时遇到一些问题,我需要一些帮助。
我有一个测试应用程序(Windows 窗体)和一个不同的类(实际上在它自己的 .dll 中,但这无关紧要)我有我的套接字代码的所有服务器/客户端代码。
问题1)
在我的测试应用程序的服务器部分,用户可以单击“开始侦听”按钮,我的套接字应用程序的服务器部分应该开始侦听指定地址和端口上的连接,到目前为止一切顺利。
但是,该应用程序将被阻止,并且在有人连接到服务器之前我无法执行任何操作。如果没有人连接怎么办?我该怎么处理?我可以指定接收超时,但那又怎样呢?它抛出异常,我该怎么办?我想要的是在主应用程序上进行某种活动,以便用户知道应用程序没有冻结并且正在等待连接。但如果没有建立连接,它应该超时并关闭所有内容。
也许我应该使用异步调用来发送/接收方法,但它们看起来很混乱,我无法使其工作,只能同步工作(我将在下面发布我当前的代码)。
问题2)
当某些发送/接收呼叫超时时,我是否需要关闭任何内容?正如您将在我当前的代码中看到的那样,我在套接字上有一堆关闭,但这感觉不太对劲。但当操作超时并且我没有关闭套接字时,感觉也不对劲。
总结我的两个问题......我想要一个不会阻塞的应用程序,以便用户知道服务器正在等待连接(例如带有一点选框动画)。如果一段时间后从未建立连接,我想关闭所有应该关闭的东西。当建立连接或者在一段时间后没有发生连接时,我想将结果通知主应用程序。
这是我的一些代码,其余的类似。这Packet
class 是一个自定义类,代表我的自定义数据单元,它只是一堆基于enums
现在,使用将它们转换为字节并返回属性的方法。
开始监听连接的函数是这样的:
public void StartListening(string address, int port) {
try {
byte[] bufferBytes = new byte[32];
if(address.Equals("0.0.0.0")) {
udpSocket.Bind(new IPEndPoint(IPAddress.Any, port));
} else {
udpSocket.Bind(new IPEndPoint(IPAddress.Parse(address), port));
}
remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int numBytesReceived = udpSocket.ReceiveFrom(bufferBytes, ref remoteEndPoint);
if(numBytesReceived == 0) {
udpSocket.Close();
return;
}
Packet syncPacket = new Packet(bufferBytes);
if(syncPacket.PacketType != PacketType.Control) {
udpSocket.Close();
return;
}
} catch {
if(udpSocket != null) {
udpSocket.Close();
}
}
}
我确信我有一堆不必要的代码,但我对此很陌生,我不确定该怎么做,非常感谢任何修复我的代码以及如何解决上述问题的帮助。
EDIT:
我可能应该声明我的要求是使用 UDP 并自己在应用层实现这些东西。您可以将其视为家庭作业,但我没有标记为这样,因为代码无关紧要,不会成为我成绩的一部分,而且我的问题(我的问题)是“如何编码”,因为我的套接字经验很少,而且不是教过。
不过,我必须说,我现在解决了我的问题,我想...我在演示应用程序上使用线程,这给我带来了一些问题,现在我在协议连接中使用它,更有意义,我可以轻松更改我的自定义协议类属性并从演示应用程序中读取这些属性。
我指定了一个超时,如果达到超时则抛出 SocketException。每当捕获到这样的异常时,套接字连接就会关闭。我只是说连接握手,仅此而已。如果没有捕获到异常,则代码可能会顺利进行并建立连接。
请相应地调整您的答案。现在,我将其中任何一个标记为已接受的答案都没有意义,希望您理解。