public bool Connect (string address, int remotePort)
{
if (_socket != null && _socket.Connected)
return true;
IPHostEntry hostEntry = Dns.GetHostEntry (address);
foreach (IPAddress ip in hostEntry.AddressList) {
try {
IPEndPoint ipe = new IPEndPoint (ip, remotePort);
_socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
break;
} catch (System.Exception e) {
PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
return false;
}
}
return true;
}
void ConnectionCallback (System.IAsyncResult ar)
{
NetBitStream stream = new NetBitStream ();
stream._socket = (Socket)ar.AsyncState;
try {
_socket.EndConnect (ar);
_socket.SendTimeout = _sendTimeout;
_socket.ReceiveTimeout = _revTimeout;
PushPacket ((ushort)MsgIds.Id.CONNECTION_REQUEST_ACCEPTED, "");
_socket.BeginReceive (stream.BYTES, 0, NetBitStream.HEADER_LENGTH, SocketFlags.None, new System.AsyncCallback (ReceiveHeader), stream);
} catch (System.Exception e) {
if (e.GetType () == typeof(SocketException)) {
if (((SocketException)e).SocketErrorCode == SocketError.ConnectionRefused) {
PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
} else
PushPacket ((ushort)MsgIds.Id.CONNECTION_LOST, e.Message);
}
Disconnect (0);
}
}
Here are two functions. When I call
client.Connect ("127.0.0.1", 10001);
It just steps over the break;
after
_socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
and goes to return true;
. I set a breakpoint at ConnectionCallback but it does not go into this function.
There is no server listening on the 10001
port.
So I think it at least should throw an exception (connect failed), then go into the catch
.
Or have I made a mistake in the two functions?
Here is a Minimal, Complete, and Verifiable example
using System;
using System.Net.Sockets;
using System.Net;
namespace TestSocket
{
class MainClass
{
public static void Main (string[] args)
{
NetTCPClient tcp_client = new NetTCPClient ();
tcp_client.Connect ("127.0.0.1", 10001);
}
}
class NetTCPClient
{
Socket _socket = null;
public bool Connect (string address, int remote_port)
{
if (_socket != null && _socket.Connected)
return true;
IPHostEntry host_entry = Dns.GetHostEntry (address);
foreach (IPAddress ip in host_entry.AddressList) {
try {
IPEndPoint ipe = new IPEndPoint (ip, remote_port);
_socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult ia = _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
break;
} catch (Exception e) {
Console.WriteLine ("Connet() catch an exception!");
return false;
}
}
return true;
}
void ConnectionCallback (System.IAsyncResult ar)
{
Console.WriteLine ("ConnectionCallback() ");
}
}
}
The debugger doesn't work that way. With very few exceptions, it will not switch threads without explicit instruction from you.
When you are stepping through the Connect()
method you wrote, you are debugging a particular thread in your program. The ConnectionCallback()
method, if and when it is called (note that it is not generally going to be called synchronously during your call to BeginConnect()
), will be called in a different thread. If you want to debug it, you need to set a breakpoint at or in the ConnectionCallback()
method itself.
With a breakpoint set in that method, you are assured that the debugger will pause the execution of your program there, regardless of which thread is executing that method.
EDIT:
Thank you for the full code example. Assuming that is in fact the code example you are testing with and having trouble with, then your problem is (as was already guessed) one of two things:
Connect()
method, you do not resume execution of your program. I.e. you did not click the "Continue" button or use the "Continue" menu item in the "Debug" menu. Or…In case #1 above, you never see the breakpoint because your program is not executing. The breakpoint can only be triggered if execution of the program does in fact arrive at the breakpoint. But the execution of your program can't arrive there if it's not happening at all.
In case #2 above, you never see the breakpoint because your program is not executing. In this case, it's because the program has exited altogether.
If you want to see the breakpoint at the ConnectionCallback()
method get triggered, you need to let the program run, and for long enough for that to happen.
As a quick proof-of-concept, I set a breakpoint at that method, and added this statement to the end of the Main()
method:
Thread.Sleep(TimeSpan.FromMinutes(5));
I then used the debugger to step through the Main()
method. It of course paused to let the program run at the above statement I'd just added, but then very quickly interrupted the program again, right at the desired breakpoint. (I didn't have to wait anywhere close to 5 minutes…I just used that as a very large time value that I was sure would be enough).
For what it's worth, I also tried a test where I stepped through the original Main()
, i.e. without the call to Thread.Sleep()
, but waited about 5-10 seconds after stepping over the call to Connect()
before proceeding. In that case, at least on my computer, I also did see the breakpoint triggered. That particular test is somewhat dependent on machine configuration, so it's less reliable than adding the call to Thread.Sleep()
. But it did work in my case.
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