Sending data - line by line

I’m a Java programmer, but I’m starting to learn C programming language. Hope someone can help me here…

My server side socket is coded using Java, and the client side is coded through C. I can telnet to the Java app and the Java app shows that the input is being received from telnet.

However, when I use my C program to connect to the Java app, it shows that they are connected, but the Java app couldn’t receive any input from the C program.

Someone told me that I need to check if the way of the C Program is sending the data is “compatible” with my Java app, but since i’m new to C, I hope someone could do a quick go through my C source below.

My Java app receives input character by character, as shown in below code:


..
try {
            if (socket.isConnected()) {
                System.out.println("Server is connected to IP: " + socket.getInetAddress() + " Port: " + socket.getPort() + "");
            }
 
            // Get data from remote device
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                    socket.getInputStream()));
 
            
            try {
                while (true) {
                    int i = in.read();
                    if (i == -1) {
                        break;
                    }
                    char c = (char) i;
                    System.out.print(c);
                }
                
            } catch (IOException e) {
                System.err.println(e);
            }

However, on my client side, it’s a C program, and sending through:
Part of main.cpp


//-----------------------------------------------------------------//
// Function: SendMessage()
// Input Params:
//    *Message : string with the message to send.
// Output Params:
// Description:
//    Sends the message using TCP or UDP socket.
//-----------------------------------------------------------------//
VOID SendMessage( CHAR *Message )
{
   INT  ReturnCode;
 
#ifdef TCP
   ReturnCode = TCP_SendData((CHAR *)IPaddr, dest_port, Message, strlen(Message));
   if(RemoteServerDisconnected || (ReturnCode == -1)) {
       Status = STOP_INET_STATE;
   }else {
      WriteTraces("TCP-> All data are sent");
   }
#else
   ReturnCode = UDP_SendData((CHAR *) IPaddr, dest_port, Message, strlen( Message));
   if(ReturnCode == -1) {
      ConnectionError = TRUE;
   } else {
      WriteTraces("UDP-> All data are sent");
   }
#endif
}

Part of socket.cpp


//-----------------------------------------------------------------//
// Function: TCP_SendData()
// Input Params:
// Output Params:
// Description:
//-----------------------------------------------------------------//
INT TCP_SendData( CHAR *ip, INT port, CHAR *buffer, INT buffer_length )
{
   struct sockaddr_in  server;
   struct hostent      *hp;
   INT                 SocketFD;
   struct timeval      timeout;
   INT                 error;
   INT                 sent_bytes = 0;
   INT                 total_bytes = 0;
   INT                 tries;

   WriteTraces("
SOCKET->TCP: TCP_SendData() start
");

	//Time outs on socket operations
   timeout.tv_sec = 5;
   timeout.tv_usec = 0;

//   sigpipe_signal.sa_handler = sigpipe_handler;
//   sigpipe_signal.sa_flags = 0;
//   sigaction(SIGPIPE, &sigpipe_signal, &sigpipe_signalOld);

   // Obtain host data
   if ((hp = gethostbyname ((CHAR*)ip)) == 0) {
      perror("gethostbyname() failed");
      return -1;
   }
   else { // We can resolve the host so we continue
      memset((CHAR*)&server, 0, sizeof(server));
      // Construct the server address structure
      server.sin_family = AF_INET;
      server.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
      server.sin_port = htons(port);

      //Obtain socket
      if ((SocketFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         perror("socket() failed");
         return -1;
      }
/*
      //Set time-out parameters
      if (setsockopt(SocketFD, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) == -1) {
		   perror("setsockopt() failed");
         close(SocketFD);
         return -1;
      }
		if (setsockopt(SocketFD, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) {
		   perror("setsockopt() failed");
         close(SocketFD);
         return -1;
      }
*/

      // Set non-blocking for the socket
      if (fcntl(SocketFD, F_SETFL, O_NONBLOCK)) {
         printf("SOCKET->TCP Error making socket file descriptor non blocking
");
         close(SocketFD);
         return -1;
      }

      WriteTraces("SOCKET->TCP: connecting to the server");

      // Conect with specified port of the server.
      // If the connection cannot be established immediately and O_NONBLOCK is set
      // for the file descriptor for the socket, connect() shall fail and set errno
      // to [EINPROGRESS], but the connection request shall not be aborted.
      // Subsequent calls to connect() for the same socket, before the connection is
      // established, shall fail and set errno to [EALREADY].
      do {
         error = connect(SocketFD, (struct sockaddr*)&server, sizeof(server));
         if ((error == -1) && (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EAGAIN)) {
//         printf("connect:%s %d
", strerror(errno), errno);
            perror("connect() failed");
            close(SocketFD);
            return -1;
         }
      }while(error != 0);

/*
      // Uncomment the following lines in case of Blocking socket.
      // Connect with specified port of the server
      if (connect(SocketFD, (struct sockaddr*)&server, sizeof(server)) == -1) {
         printf("connect: %s %d
", strerror(errno), errno);
         close(SocketFD);
         perror("connect() failed");
         return -1;
      }
*/
      WriteTraces("SOCKET->TCP: socket connected");

      tcp_fd = SocketFD;
      TCP_StartRXThread();
      (*Fncusecsleep)(1, 0);

		//Send message to the server
		do {
         WriteTraces("
SOCKET->TCP: sending %s, %d bytes
", buffer, buffer_length);

			sent_bytes = sendto(SocketFD, buffer + total_bytes, buffer_length - total_bytes, 0,
						(struct sockaddr *)&server, sizeof(server));
			if (sent_bytes == -1) {
            TCP_StopRXThread();
				close(SocketFD);
				return -1;
			}
			total_bytes += sent_bytes;
		} while(total_bytes < buffer_length);
      WriteTraces("SOCKET->TCP: send message OK");

      //Get an answer from the server
      tries = 0;
      do {
         pthread_mutex_lock(&RxLock);
         if (!rx_data_received && (tries != 1)) {
            pthread_mutex_unlock(&RxLock);
            (*Fncusecsleep)(1, 0);
         }
         else {
            if(rx_data_received) {
               pthread_mutex_unlock(&RxLock);
               break;
            }
            else
               pthread_mutex_unlock(&RxLock);
         }
      }while(tries++ < 120); // If no answer from the server wait for 2 minutes

      TCP_StopRXThread();
      close(SocketFD);
   }

//   remoteHostDisc = FALSE;
   WriteTraces("SOCKET->TCP: TCP_SendData() end");
   return 0;
}

Any idea what’s the problem?

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Wild guess… if you can connect with telnet (or, better by far,
netcat) then it is more-likely that you are using TCP, which seems
sensible in most cases; with that said you appear to be sending the data
from your C application via UDP… that will never reach your TCP port
on the remote machine unless you are doing some magic that you
definitely should have mentioned. You also don’t include the code for
your UDP function which you are using. A bit more of the Java code may
have let us see which protocol was selected.

Swap it… use TCP all around.

Good luck.

mingteikg wrote:
> I’m a Java programmer, but I’m starting to learn C programming language.
> Hope someone can help me here…
>
> My server side socket is coded using Java, and the client side is coded
> through C. I can telnet to the Java app and the Java app shows that the
> input is being received from telnet.
>
> However, when I use my C program to connect to the Java app, it shows
> that they are connected, but the Java app couldn’t receive any input
> from the C program.
>
> Someone told me that I need to check if the way of the C Program is
> sending the data is “compatible” with my Java app, but since i’m new to
> C, I hope someone could do a quick go through my C source below.
>
> My Java app receives input character by character, as shown in below
> code:
>
>
> Code:
> --------------------
>
> …
> try {
> if (socket.isConnected()) {
> System.out.println("Server is connected to IP: " + socket.getInetAddress() + " Port: " + socket.getPort() + “”);
> }
>
> // Get data from remote device
> BufferedReader in = new BufferedReader(
> new InputStreamReader(
> socket.getInputStream()));
>
>
> try {
> while (true) {
> int i = in.read();
> if (i == -1) {
> break;
> }
> char c = (char) i;
> System.out.print(c);
> }
>
> } catch (IOException e) {
> System.err.println(e);
> }
>
> --------------------
>
>
> However, on my client side, it’s a C program, and sending through:
> Part of main.cpp
>
>
> Code:
> --------------------
>
> //-----------------------------------------------------------------//
> // Function: SendMessage()
> // Input Params:
> // *Message : string with the message to send.
> // Output Params:
> // Description:
> // Sends the message using TCP or UDP socket.
> //-----------------------------------------------------------------//
> VOID SendMessage( CHAR *Message )
> {
> INT ReturnCode;
>
> #ifdef TCP
> ReturnCode = TCP_SendData((CHAR *)IPaddr, dest_port, Message, strlen(Message));
> if(RemoteServerDisconnected || (ReturnCode == -1)) {
> Status = STOP_INET_STATE;
> }else {
> WriteTraces(“TCP-> All data are sent”);
> }
> #else
> ReturnCode = UDP_SendData((CHAR ) IPaddr, dest_port, Message, strlen( Message));
> if(ReturnCode == -1) {
> ConnectionError = TRUE;
> } else {
> WriteTraces(“UDP-> All data are sent”);
> }
> #endif
> }
>
> --------------------
>
>
> Part of socket.cpp
>
> Code:
> --------------------
>
> //-----------------------------------------------------------------//
> // Function: TCP_SendData()
> // Input Params:
> // Output Params:
> // Description:
> //-----------------------------------------------------------------//
> INT TCP_SendData( CHAR ip, INT port, CHAR buffer, INT buffer_length )
> {
> struct sockaddr_in server;
> struct hostent hp;
> INT SocketFD;
> struct timeval timeout;
> INT error;
> INT sent_bytes = 0;
> INT total_bytes = 0;
> INT tries;
>
> WriteTraces("
SOCKET->TCP: TCP_SendData() start
");
>
> //Time outs on socket operations
> timeout.tv_sec = 5;
> timeout.tv_usec = 0;
>
> // sigpipe_signal.sa_handler = sigpipe_handler;
> // sigpipe_signal.sa_flags = 0;
> // sigaction(SIGPIPE, &sigpipe_signal, &sigpipe_signalOld);
>
> // Obtain host data
> if ((hp = gethostbyname ((CHAR
)ip)) == 0) {
> perror(“gethostbyname() failed”);
> return -1;
> }
> else { // We can resolve the host so we continue
> memset((CHAR
)&server, 0, sizeof(server));
> // Construct the server address structure
> server.sin_family = AF_INET;
> server.sin_addr.s_addr = ((struct in_addr )(hp->h_addr))->s_addr;
> server.sin_port = htons(port);
>
> //Obtain socket
> if ((SocketFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
> perror(“socket() failed”);
> return -1;
> }
> /

> //Set time-out parameters
> if (setsockopt(SocketFD, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) == -1) {
> perror(“setsockopt() failed”);
> close(SocketFD);
> return -1;
> }
> if (setsockopt(SocketFD, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1) {
> perror(“setsockopt() failed”);
> close(SocketFD);
> return -1;
> }
> /
>
> // Set non-blocking for the socket
> if (fcntl(SocketFD, F_SETFL, O_NONBLOCK)) {
> printf("SOCKET->TCP Error making socket file descriptor non blocking
");
> close(SocketFD);
> return -1;
> }
>
> WriteTraces(“SOCKET->TCP: connecting to the server”);
>
> // Conect with specified port of the server.
> // If the connection cannot be established immediately and O_NONBLOCK is set
> // for the file descriptor for the socket, connect() shall fail and set errno
> // to [EINPROGRESS], but the connection request shall not be aborted.
> // Subsequent calls to connect() for the same socket, before the connection is
> // established, shall fail and set errno to [EALREADY].
> do {
> error = connect(SocketFD, (struct sockaddr
)&server, sizeof(server));
> if ((error == -1) && (errno != EINPROGRESS) && (errno != EALREADY) && (errno != EAGAIN)) {
> // printf("connect:%s %d
", strerror(errno), errno);
> perror(“connect() failed”);
> close(SocketFD);
> return -1;
> }
> }while(error != 0);
>
> /

> // Uncomment the following lines in case of Blocking socket.
> // Connect with specified port of the server
> if (connect(SocketFD, (struct sockaddr
)&server, sizeof(server)) == -1) {
> printf("connect: %s %d
“, strerror(errno), errno);
> close(SocketFD);
> perror(“connect() failed”);
> return -1;
> }
> */
> WriteTraces(“SOCKET->TCP: socket connected”);
>
> tcp_fd = SocketFD;
> TCP_StartRXThread();
> (*Fncusecsleep)(1, 0);
>
> //Send message to the server
> do {
> WriteTraces(”
SOCKET->TCP: sending %s, %d bytes
", buffer, buffer_length);
>
> sent_bytes = sendto(SocketFD, buffer + total_bytes, buffer_length - total_bytes, 0,
> (struct sockaddr *)&server, sizeof(server));
> if (sent_bytes == -1) {
> TCP_StopRXThread();
> close(SocketFD);
> return -1;
> }
> total_bytes += sent_bytes;
> } while(total_bytes < buffer_length);
> WriteTraces(“SOCKET->TCP: send message OK”);
>
> //Get an answer from the server
> tries = 0;
> do {
> pthread_mutex_lock(&RxLock);
> if (!rx_data_received && (tries != 1)) {
> pthread_mutex_unlock(&RxLock);
> (*Fncusecsleep)(1, 0);
> }
> else {
> if(rx_data_received) {
> pthread_mutex_unlock(&RxLock);
> break;
> }
> else
> pthread_mutex_unlock(&RxLock);
> }
> }while(tries++ < 120); // If no answer from the server wait for 2 minutes
>
> TCP_StopRXThread();
> close(SocketFD);
> }
>
> // remoteHostDisc = FALSE;
> WriteTraces(“SOCKET->TCP: TCP_SendData() end”);
> return 0;
> }
>
> --------------------
>
>
> Any idea what’s the problem?
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJoqixAAoJEFl00+q2r0YpDrkQAIdn0i05HQ6vZ+Nr1EK7SnNv
yjmD8N/P2GIY+e2OHuOp677nyy1HrDxWgepTbJ1m0NHREfDwEVLgWDBT7zkLHExN
G03fGLc03WhkUt+VjNMQk1hWdRamdiSlbmozD+Z1yltjzzL6r9lQ+Yse71zR2LT8
FX+aTommEF3pOFjLpZMXIEc06L5IJBY8pHu9ryzK/fRKXd9ESFVbYdvkGWedgpWT
dXJGZ7erO/tHwsYof0khU57GgVUEtW/R6KrqnFSUBHohxCH75EiaENELDYsdM16E
Gnt4VHEsm1WowwkgZiLtFqruUO6LYU0bsMoys4BWzbYOw3mwjD9LrHtXi4ptoh8H
vVqaj1NtqPYSLkIkoL7jqS+GOWPUkrxq7a8jtMUmVejdjKqnyDn+xc7El1WeR+PH
AMB9q+rElO/maPAFbpG2eOVqpBjCoxgqu+o2B54wmWBC1fYdGSHO6xuFG23wMjfd
YmRMFpKrM0UxrKW2+UG+vVtqiA7hsfU3piY+SImmHFsKWZNMyjxssjkbRHSWa/kE
qVRoHzKHGGzYJbxyAIyFokX9JHYwIyWZA48U9EsOvPSN/AI6Xd2h0CmBAPYIvGmw
bqY8qAnEENQnK/MBLkmIUygoLE6uqdvxqOWj91mruiN4uhRDRJbRDbtTAzUi5yiq
g3qSvyAXiCJgA1j1+oK0
=gWqO
-----END PGP SIGNATURE-----

Hi,

I do have:
define TCP
set.

The UDP code is there for flexibity to send through UDP.

Both Java and C source code have reference to sending/receive data through TCP, if you take a closer look…

Any other suggestions? :slight_smile:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

When you telnet I presume you are doing it from a remote machine,
hopefully from the same machine as you are running the C-based
application on. This would hopefully rule out any weird
routing/firewall issues. Get a LAN trace taken simultaneously from both
sides (one from the client machine, one from the server) and post it.

Good luck.

mingteikg wrote:
> Hi,
>
> I do have:
> define TCP
> set.
>
> The UDP code is there for flexibity to send through UDP.
>
> Both Java and C source code have reference to sending/receive data
> through TCP, if you take a closer look…
>
> Any other suggestions? :slight_smile:
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJorQTAAoJEFl00+q2r0Yp7lAQAJe9H0uDZQuvvC6DfHjTjUT8
w/HqagzKKATvJBtR396fDntq+JP8WBspymzqRj3xb5aFzEt4KKyokgyCVMMFKWlt
K6x89r3fnmYe89+YQii1voZIE4leoo9lcYoMxDWuAvBVV6a4SCnTpZXgZPBVjQC9
ITZJ7ZCHnzvB5Nj0CRXJKCRt/iSQ/EPdGnDnq2bEBv6Xa5xDMtlPVYm+PZB4YCDD
biy/6e/n8KvegQYab8fgv/LkJLEHj6Wt1xDAIksq+/yvA2glOpxAPRe5qdhZByyO
Cqhc1C3ARYeRJMhmfCViAEacuIO+5mlofgJtOLF0XAr8q+LppBKT+sf1NB+uMktT
9pxZ8pCWKEMODjgbWP1KzPzY4iYprygVoulRHCqMZaAkT57dXbzEaFH519nVFVJq
ia4tQIJreOCvMCNI0kIV9LWcqLWZZEfGoNY3NHmNXwAdt0c99qMvuMGmgqHkStTb
u3IT43RRg9DJhx+6yYgCNTEU+utQjTW58BjcYvBXuA8TC4+051LeQuwB7/DVNMrL
QJoYkFQZXd8coDIa3/gvg6OM7i2z5Vp9PSBrr93aBzwhTCqHxOsIt/tCZiLnBCpe
BcDKXW86Og7a0WZIJrYFVNEa4ih+BZtyaiPylscvTaJkr0A6Tgqw8+JOWASX36Qi
1a7rpWNl0GKsu3ZbAppp
=Y28Z
-----END PGP SIGNATURE-----

The embedded device has the C client program, which connects to the server through GPRS. From the device, I can ping to the server and all.

I installed a network sniffer on the server, and I can only see the TCP handshake, implying that both the server and client are now connected. However the client reports that 39 bytes has been sent to the server, but the server couldn’t see anything. Network sniffer doesn’t even see the packet!

The client is connected through GPRS to my GSM network, so I don’t tihnk there’s any firewall issue on my end.

What do you think?

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

If you see the TCP handshake then there shouldn’t be a firewall in the
way but if you then see data from the client but you never see it on the
server side something is definitely wrong between the systems… maybe
something filtering traffic dynamically. Trace the netcat connection
from the client machine to the server machine on the same port sending
some data and ensure you see it get sent and arrive just in case this
isn’t related to your code at all. Maybe run the client and server on
the same machine if possible to rule out anything strange between the
two at all.

Good luck.

mingteikg wrote:
> The embedded device has the C client program, which connects to the
> server through GPRS. From the device, I can ping to the server and all.
>
> I installed a network sniffer on the server, and I can only see the TCP
> handshake, implying that both the server and client are now connected.
> However the client reports that 39 bytes has been sent to the server,
> but the server couldn’t see anything. Network sniffer doesn’t even see
> the packet!
>
> The client is connected through GPRS to my GSM network, so I don’t
> tihnk there’s any firewall issue on my end.
>
> What do you think?
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJor17AAoJEFl00+q2r0YpQu0P/iy4iTiqE4NpAAx/XZWjmW2D
u2a8eLlsAH9dKcIMom+ybhqQ4/yXxkpqdhK23ZSmgtKuvsZZGIcZ1KnLFDvjIEoh
bdCh2SPRt17fhJZzB+FmWk6l4GxhyrL65Hi+FkEa9BcaKnIyMGTUnVg0F8R2E5++
4POi7UnZ+kieoF0tDNlr5HhKmABXIlab6lGt6v6bM6VfDiPMsv+v7Aida6qmpdM7
utlcajpIZyFObalZil+XPkCAGPZfAdF6YVgRgemHxw6YYQHoPksjJr2OnApOXW7Y
8MdKX7e5XwlsqN6T31Za66Q1k+0VJ110HUzlDUaDvyph7qV1Hj/7x3OwR9d7WF+7
D3nQy8rairk5aK49pOICNRRfReDPZ/YNt8lk4zi9/EuBaBVmNSnCuCVjATLAohwD
+jKPyZu1+42mNFu6UwqigMZg7ms396D9kIYafb9Y2PjULPa2r57z5FZjCBFaeQ53
dsfo7vKAuyekRXO4cA2L5ZRFCwOz+rPTa87r8dUGzQ4ar6wvaQWUEhEE8CisyAKU
A1sheGS6s2JxzDcYxF68mbsCE7yKXT6zJKwRWjwA8Z4tnNzF5S2mzBNntvBvbt+M
UeLQ5p5OJBvDH4IlEBVyGhv847T+fcJFZIZOMig51+Hc4rf6FZfGlO1VYd+gIaqp
69OgsOvi6U1fHYJHBA+n
=hYoR
-----END PGP SIGNATURE-----

I glanced through your code and didn’t see anything obvious (though I certainly could have missed it). The only question is whether you should test for EALREADY. But as there are some parts of the code that aren’t posted, I have to assume that those unposted parts are functioning correctly.

ab@novell also asked an important question that I don’t think you answered: are you telnet’ing from the same machine that the C program runs on? That would positively rule out firewall and network issues.

I would strongly suggest that you try a simple C program that just transmits a hard-coded, fixed string. Use blocking sockets, no separate threads, nothing fancy. Once you have that working, start fleshing out the code with the fancier stuff.

Beej’s Guide to Network Programming is a splendid reference that walks you through socket programming in C, step-by-step. Some of it will probably be a little elementary to you, but it’s still an invaluable resource, and again, it’s all in C. I downloaded the PDF years ago and still refer to it. :slight_smile:

Personal opinion: if you’re going to use separate threads, leave the socket in the default “blocking” state and simply let the thread block as needed. Beej covers ways to bail out of a blocked socket call.

Another idea: you have trace messages in your code. Load it down with some more. You should emit a trace after each step. Use the sprintf() function to build strings for the trace-outs with useful information: ex., “value here is xxx, tries=(number of iterations.”). That’ll give you a better idea of what’s going on.