【发布时间】:2011-07-21 20:56:20
【问题描述】:
我刚刚开始通过各种 Google 搜索学习 Sockets,但在弄清楚如何在 C# 中正确使用 Sockets 时遇到了一些问题,我需要一些帮助。
我有一个测试应用程序(Windows 窗体)和一个不同的类(实际上在它自己的 .dll 中,但这无关紧要)我有我的套接字代码的所有服务器/客户端代码。
问题 1)
在我的测试应用程序中,在服务器部分,用户可以单击“开始监听”按钮,我的套接字应用程序的服务器部分应该开始监听指定地址和端口上的连接,到目前为止一切顺利。
但是,应用程序将被阻止,并且在有人连接到服务器之前我无法执行任何操作。如果没有人连接怎么办?我应该如何处理?我可以指定接收超时,但那又如何呢?它抛出一个异常,我该怎么办?我想要的是在主应用程序上进行某种活动,以便用户知道应用程序没有冻结并且正在等待连接。但是如果没有连接,它应该超时并关闭一切。
也许我应该使用异步调用来发送/接收方法,但它们看起来令人困惑,我无法让它工作,只能同步工作(我将在下面发布我当前的代码)。
问题 2)
当某些发送/接收呼叫超时时,我是否需要关闭任何东西。正如您将在我当前的代码中看到的那样,我在套接字上有一堆关闭,但这感觉不太对劲。但是当操作超时并且我没有关闭套接字时,它也感觉不对。
结束我的两个问题....我想要一个不会阻塞的应用程序,这样用户就知道服务器正在等待连接(例如,带有一点选框动画)。如果一段时间后从未建立连接,我想关闭所有应该关闭的东西。当建立连接或者一段时间后没有发生连接时,我想将结果通知主应用程序。
这是我的一些代码,其余的类似。 Packet 类是一个自定义类,代表我的自定义数据单元,目前它只是一堆基于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();
}
}
}
我确定我有一堆不必要的代码,但我是新手,我不确定该怎么做,非常感谢任何帮助修复我的代码以及如何解决上述问题。
编辑:
我可能应该说我的要求是使用 UDP 并在应用层自己实现这些东西。您可以将其视为家庭作业,但我没有这样标记,因为代码无关紧要,不会成为我成绩的一部分,而且我的问题(我的问题)在于“如何编码”,因为我的 Sockets 经验很少而且不是教过。
但是我必须说我现在解决了我的问题,我认为...我在演示应用程序上使用线程,这给我带来了一些问题,现在我在协议连接中使用它,更有意义,我可以轻松更改我的自定义协议类属性并从演示应用程序中读取这些属性。
我已经指定了一个超时时间,如果超时就抛出一个 SocketException。每当捕获到这样的异常时,套接字连接就会关闭。我只是在谈论连接握手,仅此而已。如果没有捕获到异常,则代码可能运行顺利并建立了连接。
请相应地调整您的答案。目前,我将其中任何一个标记为已接受的答案是没有意义的,希望您能理解。
【问题讨论】:
-
您将应用程序作为线程运行?
-
没有。我尝试了,但我无法实现上述目标。
标签: c# sockets networking udp