Solved

C# server socket doesn't connect to C++ client socket

Posted on 2010-09-16
4
1,511 Views
Last Modified: 2012-05-11
Hi,

I have am trying to integrate our C# interface with a vendor's C++ message simulator, but I'm having trouble getting the C# server to recognize a client connect from the C++ app.  I pulled example C# code to setup the server and I've inherited C++ client code from my vendor, so I'm not sure if the different languages are the problem or if I'm mixing async and sync sockets or what.  When I try to set a breakpoint at the client connect callback in the C# server, it is never triggered, so it is never seeing a connection.    

I'm posting the code below, but here's what I know at this point:
- the firewall is off.  
- the C# socket code has a separate C# client snippet that connects and trades messages correctly, so I know that whatever the difference is in my code, it is due to differences in the way the C++ client is implemented, because the C# server works with it's C# client.  
- same thing happens with the C++ server/client, so again, I know the problem is in the difference in implementations, because the C++ client/server work together.    
- the C++ client code never fails at the connect call - even if I don't have a server running, the client program returns a good connect call and proceeds to send 216 bytes of data after that.  
- I don't have the liberty of changing the C++ client code.  I have to make the C# server code adapt to fit the C++ client code.  
- when I run netstat while running the client and server, I never see a connection.  

So to reiterate, my end goal is to adapt the C# server code to make it work with the C++ code as is.  My code is attached.  My server code appears first (System.Net.Socket), followed by my client code (winsock).   Thanks in advance for your help.  


public void StartListen(int port)
      {
         System.Net.IPAddress ipAdd = System.Net.IPAddress.Parse("127.0.0.1");
         IPEndPoint ipLocal = new IPEndPoint(ipAdd, port);
         Console.WriteLine("Local address and port : {0}",ipLocal.ToString());
         m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

         //bind to local IP Address...
         //if ip address is allready being used write to log log
         try
         {
            m_socket.Bind(ipLocal);
         }
         catch (Exception ex)
         {
            Debug.Fail(ex.ToString(), string.Format("Can't connect to port {0}!", port));
            return;
         }
         //start listening...
         m_socket.Listen(4);
         // create the call back for any client connections...
         m_socket.BeginAccept(new AsyncCallback(OnClientConnection), null);

      }

      private void OnClientConnection(IAsyncResult asyn)
      {
         if (m_Closed)
         {
            Console.WriteLine("Socket closed");
            return;
         }

         try
         {
            m_socWorker = m_socket.EndAccept(asyn);

            RaiseClientConnected(m_socWorker);

            m_listener = new SocketListener();
            m_listener.MessageReceived += OnMessageReceived;
            m_listener.Disconnected += OnClientDisconnection;

            m_listener.StartReceiving(m_socWorker);
         }
         catch (ObjectDisposedException odex)
         {
            Debug.Fail(odex.ToString(), "OnClientConnection: Socket has been closed");
         }
         catch (Exception sex)
         {
            Debug.Fail(sex.ToString(), "OnClientConnection: Socket failed");
         }

      }

      private void OnClientDisconnection(Socket socket)
      {
         RaiseClientDisconnected(socket);

         // Try to re-establish connection
         //m_socket.BeginAccept(new AsyncCallback(OnClientConnection), null);
         m_socket.Accept();
         if (m_socket.Connected)
            Console.WriteLine("Connected");
      }

      public void SendMessage(string mes)
      {
         if (m_socWorker == null)
         {
            return;
         }

         try
         {
            Object objData = mes;
            byte[] byData = System.Text.Encoding.ASCII.GetBytes(objData.ToString());
            m_socWorker.Send(byData);
         }
         catch (SocketException se)
         {
            Debug.Fail(se.ToString(), string.Format("Message '{0}' could not be sent", mes));
         }

      }

      public void Close()
      {
         try
         {
            if (m_socket != null)
            {
               m_Closed = true;

               if (m_listener != null)
               {
                  m_listener.StopListening();
               }

               m_socket.Close();

               m_listener = null;
               m_socWorker = null;
               m_socket = null;
            }
         }
         catch (ObjectDisposedException odex)
         {
            Debug.Fail(odex.ToString(), "Stop failed");
         }
      }

      private void OnMessageReceived(string message)
      {
         if (MessageReceived != null)
         {
            MessageReceived(message);
         }
      }

      private void RaiseClientConnected(Socket socket)
      {
         if (ClientConnect != null)
         {
            ClientConnect(socket);
         }
      }
}

Open in new window

bool SendMsg(char* host, int port, char* msg, size_t msgLength)
{
#ifdef WIN32
  // Start Winsock.
  WSAData wsaData;
  WSAStartup(MAKEWORD(1, 1), &wsaData);
#endif

  // Create socket.
  SOCKET theSocket = socket(AF_INET, SOCK_DGRAM, 0);
  if (theSocket != INVALID_SOCKET) 
  {
    // Connect.
    unsigned long address = inet_addr(host);
    if (address != INADDR_NONE) // broadcast address is illegal
    {
      sockaddr_in destination;
      destination.sin_family = AF_INET;
      destination.sin_addr.s_addr = address;
      destination.sin_port = htons((u_short)port);
      memset(&(destination.sin_zero), '\0', 8);

      connect(theSocket,(LPSOCKADDR)(&destination),sizeof(destination));

      // Send message.
      int bytesSent;
      bytesSent = sendto(theSocket, msg, (int)msgLength, 0, 
        (sockaddr*)&destination, sizeof(sockaddr_in));

      // Shutdown socket.
      shutdown(theSocket, 0x01);
    }
    else
    {
      cerr << "The destination IP address is not valid. Note: The IP address 255.255.255.255 cannot be used." << endl;
      return true;
    }
  }
  else
  {
    cerr << "Error creating socket." << endl;
    return true;
  }

Open in new window

0
Comment
Question by:ImagineWhirledPeas
  • 3
4 Comments
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 500 total points
Comment Utility
Just taking a cursory glance now...you're binding your listener to 127.0.0.1, which means it'll only accept connections specifically addressed to 127.0.0.1 - if you're client is attempting to connect to the system's IP address 192.168.5.60 (or whatever it's address actually is) it won't work.  If you want to accept connections on the specified port for all IP addresses on this system, you can bind to IPAddres.Any (or 0.0.0.0).
With the C# server running, are you able to "telnet 127.0.0.1 <port number>" and get a connection, or does it time out?
The fact that the client is in C++ should be totally irrelevant - it shouldn't even matter if it's Windows, Mac, Linux or a BlackBerry - a TCP socket is a TCP socket any way you slice it.
0
 

Author Comment

by:ImagineWhirledPeas
Comment Utility
tgerbert, thank you for responding.  I have added the IPAddress.Any to the IPEndPoiint and still have problems.  

As for the telnet idea, when I try to establish a telnet session, it errors out immediately.  However, an SSL connection actually connects to my application.  That makes me wonder if I'm initializing a different type of socket on one side than is being initialized on the other?  

I tried changing the Socket type to Datagram, but the connection is refused after when I do that.  
0
 

Author Comment

by:ImagineWhirledPeas
Comment Utility
Thans tgerbert -- your comment made me realize that I was trying to use a stream socket with a UDP.  i changed my code to be a UDP listener and it is working now.  This is a link to UDP example code if anyone is interested.  

http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/92846ccb-fad3-469a-baf7-bb153ce2d82b/
0
 

Author Closing Comment

by:ImagineWhirledPeas
Comment Utility
The suggestion included the debugging tools I needed to figure out I was using the wrong socket type.  
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Network ports are the threads that hold network communication together. They are an essential part of networking that can be easily ignore or misunderstood, my goals is to show those who don't have a strong network foundation how network ports opera…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now