Qualcuno può spiegarmi perché il seguente codice non funziona?Problema di socket durante l'utilizzo della filettatura
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace SocketThreadingTest
{
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(delegate()
{
BeginConnect(new IPEndPoint("some address"));
});
t.Start();
Console.ReadKey();
}
public static void BeginConnect(IPEndPoint address)
{
try
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(address, ConnectCallback, socket);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private static void ConnectCallback(IAsyncResult ar)
{
Socket sock = (Socket)ar.AsyncState;
try
{
sock.EndConnect(ar);
Console.WriteLine("Connected {0}", sock.LocalEndPoint);
sock.Send(Encoding.UTF8.GetBytes("Hello"));
Console.WriteLine("success");
sock.Close();
}
catch (Exception ex)
{
Console.WriteLine("send ex " + ex);
if (sock != null)
sock.Close();
}
}
}
}
L'uscita è (notare il punto finale locale del socket):
Connected 0.0.0.0:28142
send ex System.Net.Sockets.SocketException: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram
socket using a sendto call) no address was supplied
at System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, So
cketFlags socketFlags)
at System.Net.Sockets.Socket.Send(Byte[] buffer)
at SocketThreadingTest.Program.ConnectCallback(IAsyncResult ar) in Program.cs:line 44
Naturalmente, quando non uso un filo e chiamo BeginConnect direttamente funziona bene. Ciò che è ancora più sconcertante è che l'aggiunta di un Thread.Sleep che è abbastanza lungo (1 secondo) funziona anche bene. Qualche idea? Grazie.
Il filo si crea che chiama BeginConnect esce dopo BeginConnect si chiama. Vedete un comportamento diverso se non lasciate che quel thread finisca (le note dei documenti API ci sono problemi se il thread che chiama sock.BeginConnect termina anche se dovrebbe essere un problema su un socket precedentemente connesso) – nos
Sì, c'è una differenza. Come ho detto, anche aggiungere un po 'di sonno dopo aver chiamato Program.BeginConnect fa questo lavoro. Il documento API dichiara: "Se questo socket è stato disconnesso in precedenza, BeginConnect deve essere chiamato su un thread che non verrà chiuso fino al completamento dell'operazione. Si tratta di una limitazione del provider sottostante." Ma come hai detto questo è un nuovo socket e non è stato precedentemente disconnesso ... – Zvika