socket.beginconnect

Drstein99

Junior Contributor
Joined
Sep 26, 2003
Messages
283
Location
Audubon, Nj
I'm using:

dim mySocket as New Socket(ipepCallIpEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)

mySocket.BeginConnect(ipCallIpEndPoint, AddressOf Me.tempCallConnect, mySocket)

----------

and finding that after it fails, it takes too long for me (the default time). I want it to return or timeout after say 1 second or 2 seconds, and not 5-10 seconds.

So i set the following options:

mySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, SocketOptionName.DontLinger)

mySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000)

mySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000)

------------------

AND they don't seem to have any effect. Can anyone advise please? thanks.
-----------
 
I guess SendTimeout, ReceiveTimeout only applies to a connected socket, and I can't find a builtin way to set a timeout for a socket connect. I think your best bet is to make a static method that does something like this.

Code:
public sealed class SocketConnector
{
	/// <summary>
	/// The wait handle to use to perform the time-out.
	/// </summary>
	private readonly AutoResetEvent _waitHandle;
	
	/// <summary>
	/// The object to perform thread synchronization.
	/// </summary>
	private readonly object _locker;

	/// <summary>
	/// The method to invoke on EndConnect.
	/// </summary>
	private AsyncCallback _callback;

	/// <summary>
	/// Determines if the <see cref="WaitHandle"/> has been disposed.
	/// </summary>
	private bool _disposed;

	/// <summary>
	/// Asynchronously performs a <see cref="Socket.Connect"/> and will return when either the timeout period
	/// lapses or the <see cref="Socket"/> has connected.
	/// </summary>
	/// <param name="socket">The <see cref="Socket"/> to call connect on.</param>
	/// <param name="endPoint">The <see cref="EndPoint"/> to connect to.</param>
	/// <param name="timeOut">The amount of time to wait for the connect to complete.</param>
	/// <param name="state">The object state.</param>
	/// <param name="callBack">The method to invoke when the timeout period has lapsed - or - The <see cref="Socket"/> has connected.</param>
	public static void AsynchronousConnect(Socket socket, EndPoint endPoint, TimeSpan timeOut, object state, AsyncCallback callBack)
	{
		new SocketConnector(socket, endPoint, timeOut, state, callBack);
	}

	/// <summary>
	/// Asynchronously performs a <see cref="Socket.Connect"/> and will return when either the timeout period
	/// lapses or the <see cref="Socket"/> has connected.
	/// </summary>
	/// <param name="socket">The <see cref="Socket"/> to call connect on.</param>
	/// <param name="endPoint">The <see cref="EndPoint"/> to connect to.</param>
	/// <param name="timeOut">The amount of time to wait for the connect to complete.</param>
	/// <param name="state">The object state.</param>
	/// <param name="callBack">The method to invoke when the timeout period has lapsed - or - The <see cref="Socket"/> has connected.</param>
	private SocketConnector(Socket socket, EndPoint endPoint, TimeSpan timeOut, object state, AsyncCallback callBack)
	{
		if(socket == null)
			throw new ArgumentNullException("socket");
		if(endPoint == null)
			throw new ArgumentNullException("endPoint");
		if(callBack == null)
			throw new ArgumentNullException("callBack");
		_locker = new object();
		_disposed = false;
		_callback = callBack;
		_waitHandle = new AutoResetEvent(false);
		try
		{
			IAsyncResult result = socket.BeginConnect(endPoint, new AsyncCallback(EndConnect), state);
			_waitHandle.WaitOne(timeOut, false);
			lock(_locker)
			{
				if(_callback == null)
					return;
				_disposed = true;
				socket.Close();
			}
		}
		finally
		{
			_waitHandle.Close();
		}
	}

	private void EndConnect(IAsyncResult result)
	{
		lock(_locker)
		{
			if(_callback == null)
				return;
			try
			{
				_callback.DynamicInvoke(new object[] {result});
			}
			finally
			{
				_callback = null;
				if(!_disposed)
					_waitHandle.Set();
			}
		}
	}

	static void Main()
	{
		handle = new System.Threading.AutoResetEvent(false);
		while(true)
		{
			Console.Write("ENTER IP: ");
			string ipAddress = Console.ReadLine();
			Console.Write("ENTER PORT: ");
			int port = int.Parse(Console.ReadLine());
			Console.Write("ENTER TIMEOUT (SECONDS): ");
			double timeout = double.Parse(Console.ReadLine());
			Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			IPEndPoint endpoint = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port);
			handle.Reset();
			AsynchronousConnect(socket, endpoint, TimeSpan.FromSeconds(timeout), socket, new AsyncCallback(FIN));
			handle.WaitOne();
		}
	}

	static AutoResetEvent handle;

	private static void FIN(IAsyncResult result)
	{
		Socket socket = (Socket) result.AsyncState;
		Console.WriteLine(socket.Connected);
		socket.Close();
		handle.Set();
	}
}

It's C#, ur VB, I'm sorry but I don't know VB.
 
I am a vb programmer stuggleing to understand tcp connections and threading. C sharp code translation confuses me and often makes it more difficult to understand.

I appreciate the advice, since both languages operate the same (from what I know), so the same rules apply and we can simply discuss how to handle them.

I've researched this for about 4 hours now, and am finding the same conclusion. I've wrote a temporary timer that expires and executes code to determine if it found a connection or not, and then handle itself accordingly, which so far seems to operate with success during my testing.
 
Back
Top