Can someone please explain me why the following code doesn't work?
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();
}
}
}
}
The output is (note the local end point of the 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
Of course when I don't use a thread and call BeginConnect directly it works fine. What's even more puzzling is that adding a Thread.Sleep that is long enough (1 sec) it also works fine. Any ideas? Thanks.
Which makes sense to use separate Thread and BeginConnect? If you creating separate thread (with Thread pool preferably) why are you using asynchronous connection (in this case separate thread will be taken from the thread pool)?
There are several options: Use ThreadPool and Socket.Connect
class Program {
static void Connect(object o)
{
IPEndPoint address = (IPEndPoint)o;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(address);
Console.WriteLine("Connected {0}", socket.LocalEndPoint);
socket.Send(Encoding.UTF8.GetBytes("Hello"));
Console.WriteLine("success");
socket.Close();
}
static void Main(string[] args)
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, 5111);
ThreadPool.QueueUserWorkItem(Connect, endPoint);
Console.ReadKey();
}
}
Use BeginConnect without separate thread.
class Program {
static void Main(string[] args)
{
BeginConnect(new IPEndPoint(IPAddress.Loopback, 5111));
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();
}
}
}
Use BeginConnect with separate thread:
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(delegate()
{
BeginConnect(new IPEndPoint(IPAddress.Loopback, 5111));
});
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With