Quando o Cliente tenta se conectar a um endereço IP desconectado, ocorre um longo tempo limite de mais de 15 segundos ... Como podemos reduzir esse tempo limite? Qual é o método para configurá-lo?
O código que estou usando para configurar uma conexão de soquete é o seguinte:
try
{
m_clientSocket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(serverIp);
int iPortNo = System.Convert.ToInt16(serverPort);
IPEndPoint ipEnd = new IPEndPoint(ip, iPortNo);
m_clientSocket.Connect(ipEnd);
if (m_clientSocket.Connected)
{
lb_connectStatus.Text = "Connection Established";
WaitForServerData();
}
}
catch (SocketException se)
{
lb_connectStatus.Text = "Connection Failed";
MessageBox.Show(se.Message);
}
null
nocallback
e você planejaEndConnect()
, se o socket foi,closed
então isso vai te dar uma exceção. Portanto, certifique-se de verificar ...AsyncWaitHandle.WaitOne
será sinalizado, mas o soquete permanecerá desconectado.Minha vez:
fonte
SocketExtension
, você ainda não usou.Connected
para ver se está e não está usandosocket.Connected = true;
para definirsuccess
.Acabei de escrever uma classe de extensão para permitir tempos limite nas conexões. Use-o exatamente como faria com os
Connect()
métodos padrão , com um parâmetro extra chamadotimeout
.fonte
socket.EndConnect
leva cerca de 10 segundos para fechar, então a função retorna não após o intervalo de tempo, mas após o intervalo de tempo + tempo final de conexãoEu não programo em C #, mas em C, resolvemos o mesmo problema tornando o soquete não bloqueante e, em seguida, colocando o fd em um loop de seleção / pesquisa com um valor de tempo limite igual ao tempo que estamos dispostos a esperar pela conexão ter sucesso.
Achei isso para Visual C ++ e a explicação lá também se inclina para o mecanismo de seleção / votação que expliquei antes.
Na minha experiência, você não pode alterar os valores de tempo limite de conexão por soquete. Você muda para todos (ajustando os parâmetros do sistema operacional).
fonte
pode ser tarde demais, mas há uma solução interessante baseada em Task.WaitAny (c # 5 +):
fonte
Resolvi o problema usando o método Socket.ConnectAsync em vez do método Socket.Connect. Após invocar o Socket.ConnectAsync (SocketAsyncEventArgs), inicie um cronômetro (timer_connection), se o tempo acabou, verifique se a conexão do soquete está conectada (if (m_clientSocket.Connected)), se não, pop up timeout error.
fonte
Verifique isso no MSDN . Não parece que você pode fazer isso com as propriedades implementadas na classe Socket.
O pôster no MSDN realmente resolveu seu problema usando threading. Ele tinha um encadeamento principal que chamava outros encadeamentos que executam o código de conexão por alguns segundos e, em seguida, verificam a propriedade Connected do soquete:
O que você está tentando fazer e por que não pode esperar 15-30 segundos antes de expirar?
fonte
Eu tive o mesmo problema ao conectar a um soquete e eu vim com a solução abaixo, funciona bem para mim. `
fonte
Trabalhei com o Unity e tive alguns problemas com o BeginConnect e outros métodos assíncronos do socket.
Há algo que eu não entendo, mas os exemplos de código anteriores não funcionam para mim.
Então, escrevi este código para fazê-lo funcionar. Eu testei em uma rede adhoc com android e pc, também em local no meu computador. Espero que possa ajudar.
e há um watchdog muito simples em C # para fazê-lo funcionar:
fonte
É como a resposta do FlappySock, mas adicionei um retorno de chamada porque não gostei do layout e de como o booleano estava sendo retornado. Nos comentários dessa resposta de Nick Miller:
Então, para mim, parece que confiar no que é devolvido pode ser perigoso - prefiro usar
socket.Connected
. Defino um Booleano anulável e atualizo-o na função de retorno de chamada. Também descobri que nem sempre termina de relatar o resultado antes de retornar à função principal - eu também cuido disso e faço esperar pelo resultado usando o tempo limite:Relacionado: Como verificar se estou conectado?
fonte
Deve haver uma propriedade ReceiveTimeout na classe Socket.
Propriedade Socket.ReceiveTimeout
fonte
ReceiveTimeout
- destina-se estritamente ao recebimento comBeginReceive
eEndReceive
. Não há equivalente para quando você apenas vê se está conectado.