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
Solved

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

Posted on 2010-09-16
4
1,598 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
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

Manage your data center from practically anywhere

The KN8164V features HD resolution of 1920 x 1200, FIPS 140-2 with level 1 security standards and virtual media transmissions at twice the speed. Built for reliability, the KN series provides local console and remote over IP access, ensuring 24/7 availability to all servers.

Question has a verified solution.

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

Trying to figure out group policy inheritance and which settings apply where can be a chore.  Here's a very simple summary I've written which might help.  Keep in mind, this is just a high-level conceptual overview where I try to avoid getting bogge…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

828 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