我创建了一个服务器“midman”应用程序,它使用套接字和多线程技术(ServerListener在新线程中运行)。我很早就发现当我使用Socket.Accept()方法时,程序将无限期挂起,等待连接发生。问题是,据我所知,没有理由不这样做。
我花了很多时间尝试了许多不同的东西来使它工作,某些地方发生了变化,因为它突然开始工作了一段时间。但是,一旦我意外地为客户端应用程序选择了与“localhost”不同的数据源,问题就会再次弹出。我已经尝试在没有防火墙或防病毒运行的情况下运行程序,但没有运气。客户端程序设置为在端口10000上连接。这是我的代码:
public void ServerListener() {
UpdateStatus("Establishing link to server");
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(new IPEndPoint(IPAddress.Any, defaultPort));
server.Listen(queue);
UpdateStatus("Accepting Connections");
while (true) {
Socket client = default(Socket);
try {
client = server.Accept();
if (client != null) {
++count;
UpdateCount(count.ToString());
new Thread(
() => {
Client myclient = new Client(client, defaultPort, this);
}
).Start();
}
}
catch( Exception ex ){
MessageBox.Show(ex.ToString());
client.Close();
}
}
}
它将运行正常直到server.Accept(),然后挂起。如前所述,它确实提前了一段时间,但现在再次悬挂。我试过看看是否有其他程序正在使用端口10000,而它们不是。我和一位朋友一遍又一遍,我们找不到问题。请帮忙!
编辑为了清楚起见,我知道Accept是一个阻止呼叫。客户端程序在端口10000上建立连接,但是此程序继续等待Accept,就好像什么都没发生一样。它确实工作了一段时间,所以我知道连接的工作方式与客户端程序的结果一样。但是,我无法理解为什么这个程序现在表现得像连接永远不会发生,并继续等待接受。
答案 0 :(得分:3)
Accept
故意阻止。如果您想在等待其他客户连接时做其他事情,您可以:
在另一个线程中运行ServerListener
或更好 - 一个长时间运行的任务:
using System.Threading.Tasks;
...
Task.Factory.StartNew(ServerListener, TaskCreationOptions.LongRunning);
使用AcceptAsync
method使用SocketAsyncEventArgs
class。为此,您需要创建一个新的SocketAsyncEventArgs
实例,设置其值并将其传递给socket.AcceptAsync
。
答案 1 :(得分:0)
如果它在localhost中工作,但在真实网络上没有,我相信,你遇到了数据包丢失。也许您期望当数据包丢失时,tcp将自动重新传输。它不像那样工作。
EG。如果发送非常小的数据包(1个字符),并且数据包被丢弃,客户端将不会重新发送丢弃的数据包,服务器将不会请求客户端重新发送。
您可以阅读tcp可靠的数据传输,了解它的实际工作方式。接受异步只接受异步,它不会解决你有关丢失数据包的问题。