Solved

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

Posted on 2010-09-16
4
1,698 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 500 total points
ID: 33703868
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
ID: 33704494
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
ID: 33704840
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
ID: 33704863
The suggestion included the debugging tools I needed to figure out I was using the wrong socket type.  
0

Featured Post

Create the perfect environment for any meeting

You might have a modern environment with all sorts of high-tech equipment, but what makes it worthwhile is how you seamlessly bring together the presentation with audio, video and lighting. The ATEN Control System provides integrated control and system automation.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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.
Resolve DNS query failed errors for Exchange
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…

717 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