Может кто-нибудь объяснить мне, почему следующий код не работает?Проблема с розеткой при использовании резьбы
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();
}
}
}
}
Выход (обратите внимание на локальную конечную точку сокета):
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
Конечно, когда я не использую нить и называем BeginConnect непосредственно работает нормально. Что еще более озадачивает, так это добавление Thread.Sleep, который достаточно длинный (1 сек), он также отлично работает. Любые идеи? Спасибо.
Нить вы создаете, что вызывает BeginConnect выход после BeginConnect называется. Вы видите какое-либо другое поведение, если вы не позволяете этому концу потока (в документах API есть проблемы, если поток, вызывающий sock.BeginConnect, заканчивается, хотя это должно быть проблемой только для ранее подключенного сокета) – nos
Да, есть разница. Как я уже сказал, даже добавление небольшого сна после вызова программы.BeginConnect делает эту работу. В документе API указано: «Если этот сокет ранее был отключен, необходимо вызвать BeginConnect в потоке, который не будет завершен, пока операция не будет завершена. Это ограничение основного поставщика». Но, как вы заявили, что это новый сокет и ранее не был отключен ... – Zvika