Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi,

I would like to know is it possible to run server and client communication in two different systems. One acting as a server and the other acting as client?

With the server sending data to the client and the client should read it.

Server code:

XML
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

  int main()
{
  int welcomeSocket, newSocket;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  struct sockaddr_storage serverStorage;
  socklen_t addr_size;

  /*---- Create the socket. The three arguments are: ----*/
  /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
  welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);

  /*---- Configure settings of the server address struct ----*/
  /* Address family = Internet */
  serverAddr.sin_family = AF_INET;
  /* Set port number, using htons function to use proper byte order */
  serverAddr.sin_port = htons(6777);
  /* Set IP address to localhost */
  serverAddr.sin_addr.s_addr = INADDR_ANY;
  /* Set all bits of the padding field to 0 */
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

  /*---- Bind the address struct to the socket ----*/
  bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));

  /*---- Listen on the socket, with 5 max connection requests queued ----*/
  if(listen(welcomeSocket,5)==0)
    printf("Listening\n");
  else
    printf("Error\n");

  /*---- Accept call creates a new socket for the incoming connection ----*/
  addr_size = sizeof serverStorage;
  newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);

  /*---- Send message to the socket of the incoming connection ----*/
  strcpy(buffer,"Hello World \n");
  send(newSocket,buffer,13,0);

  return 0;
}



Client Code:

XML
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main()

{

  int clientSocket;
  char buffer[1024];
  struct sockaddr_in serverAddr;
  socklen_t addr_size;

  /*---- Create the socket. The three arguments are: ----*/
  /* 1) Internet domain 2) Stream socket 3) Default protocol (TCP in this case) */
  clientSocket = socket(PF_INET, SOCK_STREAM, 0);

  /*---- Configure settings of the server address struct ----*/
  /* Address family = Internet */
  serverAddr.sin_family = AF_INET;
  /* Set port number, using htons function to use proper byte order */
  serverAddr.sin_port = htons(6777);
  /* Set IP address to localhost */
  serverAddr.sin_addr.s_addr = INADDR_ANY;
  /* Set all bits of the padding field to 0 */
  memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

  /*---- Connect the socket to the server using the address struct ----*/
  addr_size = sizeof serverAddr;
  connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

  /*---- Read the message from the server into the buffer ----*/
  recv(clientSocket, buffer, 1024, 0);

  /*---- Print the received message ----*/
  printf("Data received: %s",buffer);

  return 0;

}
Posted
Updated 27-Apr-15 1:39am
v3
Comments
Mehdi Gholam 27-Apr-15 7:14am    
Yes.
venkat28vk 27-Apr-15 7:19am    
i have tried with the code, from my system to my friends system in LAN, but it is not working. Could you assist me in resolving this issue.
Mehdi Gholam 27-Apr-15 7:22am    
Disable your firewalls and try again.
venkat28vk 27-Apr-15 7:29am    
i shall try, thanks
venkat28vk 27-Apr-15 7:36am    
I tried by disabling the firewall, but it is not working.

The error is in the addressing.
While in the server the line:
C++
/* Set IP address to localhost */
serverAddr.sin_addr.s_addr = INADDR_ANY;

Works anyway because the IP stack routes all incoming connections from any of local ports to the listening socket, this is an error on the client side.
The client in this case is trying to connect to the local machine where there is no server, because it is on a different machine.
So having both server and client on the same machine works because the pseudoaddress LOCALHOST is the same so the two programs can talk each other.
But when server and client stay on different machines this is an error!
To make it work you have to specify the real server address in the client code.
I.e. if the server address is 192.168.1.23 you have to code the client program this way:
C++
/* Set server IP address to real server address in client code */
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.23");
 
Share this answer
 
v3
Comments
venkat28vk 28-Apr-15 1:35am    
You are saying to specify the ip address of the server in client code and in server address can i put it as INADDR_ANY or do i need to change to client ip address
Frankie-C 28-Apr-15 3:54am    
You already solved, but for sake of precision I'll detail it better:
The server is waiting for incoming connections, and it waits for connections at local machine address. Putting INADDR_ANY as address for the server means wait for connections and manage all of them directed to *this* machine (localhost is always referred gto local machine IP address).
On the client side however you cannot say connect to a server on localhost address (that is the machine where the client is running, but not the server). You must specify the address where the connection should look for the server.
I hope it is clear now.
venkat28vk 28-Apr-15 1:37am    
As per you said the connection has been established, but the file is not getting transferred. Could you say what could be the problem and are there any issues regarding firewall?
Frankie-C 28-Apr-15 4:44am    
What file?
You mean the message "Hello World"?
If so which errors you got?
venkat28vk 28-Apr-15 5:18am    
I am trying to send a audio file from my system to another system. There is no error but the file is not written there.
There is a very big mess in data, variables size and all the rest...
You have cut and paste the code from somewhere modifying it almost blindly. In particular you have enlarged everything you could, buffers, sizes and so on. You have allocated buffers of many Mb on the stack...
To make it work replace the routines:
- in the client:
C++
int receive_audio(long long int socket)
{

	long int buffersize = 0, recv_size = 0, size = 0, read_size, write_size;

	char verify = '1';

	FILE *audio;

	//Find the size of the audio
	recv(socket, (char *)&size, sizeof(int), 0);

	//Send our verification signal
	send(socket, &verify, sizeof(char), 0);

	//Make sure that the size is bigger than 0
	if (size <= 0)
	{
		printf("Error has occurred. Size less than or equal to 0 \n");
		return -1;
	}

	audio = fopen("/home/sosdt009/Desktop/received.mp3", "w");

	if (audio == NULL)
	{
		printf("Error has occurred. audio file could not be opened \n");
		return -1;
	}

	//Loop while we have not received the entire file yet

	while (recv_size < size)
	{
		ioctl(socket, FIONREAD, &buffersize);

		//We check to see if there is data to be read from the socket 
		if (buffersize > 0)
		{
			char *pBuf = malloc(buffersize);
			if (!pBuf)
			{
				fprintf(stderr, "Memory Error. Cannot allocate!\n");
				exit(-1);
			}

			read_size = recv(socket, pBuf, buffersize, 0);
			if (read_size  < 0)
			{
				printf("%s", strerror(errno));
			}

			//Write the currently read data into our audio file
			write_size = fwrite(pBuf, 1, buffersize, audio);

			free(pBuf);

			//Increment the total number of bytes read
			recv_size += read_size;
		}
	}

	fclose(audio);
	printf("audio successfully Received! \n");
	return 1;
}


- In the server:
C++
int send_audio(long long int socket)
{

	FILE *audio;
	long int size, read_size, stat, packet_index;
	char send_buffer[512], read_buffer[512];
	packet_index = 1;

	audio = fopen("/home/sosdt009/Desktop/ROBO.mp3", "r");

	if (audio == NULL)
	{
		printf("Error Opening audio File");
		exit(-1);
	}

	printf("Getting audio Size\n");

	fseek(audio, 0, SEEK_END);
	size = ftell(audio);
	fseek(audio, 0, SEEK_SET);
	printf("Total audio size: %li \n", size);

	//Send audio Size
	printf("Sending audio Size\n");
	send(socket, (void *)&size, sizeof(size), 0);

	printf("Sending audio as Byte Array\n");

	do
	{
		//Read while we get errors that are due to signals.
		stat = recv(socket, read_buffer, 255, 0);
		printf("Bytes read: %li \n", stat);

	} while (stat < 0);

	printf("Received data in socket\n");
	printf("Socket data: %s\n", read_buffer);

	while (!feof(audio))
	{

		//Read from the file into our send buffer
		read_size = fread(send_buffer, 1, sizeof(send_buffer), audio);

		//Send data through our socket 
		do
		{
			stat = send(socket, send_buffer, read_size, 0);
		} while (stat < 0);

		printf("Packet %li, sent %li bytes.\n", packet_index, read_size);

		packet_index++;
	}

	return 0;
}
 
Share this answer
 
v2
Comments
venkat28vk 29-Apr-15 5:42am    
I tried the above code between two different systems as client and server, but still i am not able to see the file in the desired path. Are there any other changes to be made.
Frankie-C 29-Apr-15 7:31am    
Have you updated server address with the address of the server machine?
venkat28vk 29-Apr-15 8:11am    
Everything is working fine now. Thanks for the help you have provided. I am able transfer audio files between two systems. Thanks a lot for what you have given. I have next tried with the images and video, the data is getting transferred but the file is not playing and in image there is an error message shown, when the image is opened in the received side. What could be the causes of errors?
Frankie-C 29-Apr-15 9:03am    
If the problem is present only for files > 2Gb the probllem is that in my sample the length variablle is a 32 bits integer.
venkat28vk 30-Apr-15 0:25am    
I am just sending a file of size 2-5 MB, in image and also video but that it not working. I am able to receive the file but it is not playing.
This is a more sophisticated version that can be compiled on linux (tested on UBUNTU) and on windows (test OS Win7).
It transfers more files. It is not optimized. It has not all checks required.

Include file preamble.h
C++
//File preamble.h

typedef struct
{
	long long llSize;
	char FileName[500];
	char Reserved[8];
} FILEDATA;


The server:
C++
	#ifdef __linux__
	#define _FILE_OFFSET_BITS 64
	#else
	#include <winsock2.h>
	#endif

	#include <stdio.h>
	#include <stdlib.h>
	#include <errno.h>
	#ifdef __linux__
	#include <unistd.h>
	#include <string.h>
	#include <sys/socket.h>
	#include <sys/ioctl.h>
	#include <netinet/in.h>
	#include <arpa/inet.h>
	#define WINBIN
	#else
	#define WINBIN "b"
	#define close closesocket
	#define ftell _ftell64
	#define ioctl ioctlsocket
	typedef int socklen_t;
	#endif
	#include "preamble.h"

char *file[] = { "mp3.mp3"  ,
				 "image.jpg",
				 "film.mkv"
				};
 #ifdef __linux__
 char Path[] = "/media/sf_UnixShares/";
 #else
 char Path[] = "C:\\Users\\UnixShares\\";
 #endif

int SendFile(int socket, char *FileName)
{
	FILEDATA fd;
	FILE *fp;
	long int read_size, stat, packet_index;
	long long int size=0;
	char send_buffer[512];
	char read_buffer[512];
	char LocFname[1024];
	packet_index = 1;

	memset(&fd, 0, sizeof(fd));
	strcpy(LocFname, Path);
	strcat(LocFname, FileName);
	fp = fopen(LocFname, "r" WINBIN);
	
	if (fp == NULL)
	{
		printf("Error Opening File \"%s\"\n", FileName);
		exit(-1);
	}

	printf("Getting file Size\n");

	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	fd.llSize = size;
	printf("Total file size: %lli \n", size);

	//Send file preamble
	strcpy(fd.FileName, FileName);
	printf("Sending file preamble\n");
	send(socket, (void *)&fd, sizeof(fd), 0);

	//Wait for client acknowledge
	do
	{
		//Read while we get errors that are due to signals.
		stat = recv(socket, read_buffer, 255, 0);
		printf("Bytes read: %li \n", stat);
	} while (stat < 0);
	printf("Received preamble acknowledge <%5s>\n", read_buffer);
	if (strncmp("OK", read_buffer, 5))
	{
		printf ("Transfer aborted!\n");
		return 0;
	}

	printf("Press Enter to send file: ...");
	getchar();
	printf("\rSending file\n");

	while (!feof(fp))
	{
		//Read from the file into our send buffer
		read_size = fread(send_buffer, 1, sizeof(send_buffer), fp);

		//Send data through our socket 
		do
		{
			stat = send(socket, send_buffer, read_size, 0);
		} while (stat < 0);

		printf("\rPacket %li, sent %li bytes.", packet_index, read_size);

		packet_index++;

		//Zero out our send buffer
		memset(send_buffer, 0, sizeof(send_buffer));
	}
	
	printf("\nFile sent!\n");

	return 1;
}

int main(int argc, char *argv[])
{
	long long int socket_desc, new_socket, c;
	struct sockaddr_in server, client;

 #if defined(__WIN32__) || defined(_WIN32)
    //----------------------
    // Declare and initialize variables.
    int iResult;
    WSADATA wsaData;

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR)
	{
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
 #endif

	//Create socket
	socket_desc = socket(AF_INET, SOCK_STREAM, 0);
	if (socket_desc == -1)
	{
		printf("Could not create socket");
	}

	//Prepare the sockaddr_in structure
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(6888);

	//Bind

	if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
	{
		puts("bind failed");
		return 1;
	}

	puts("Bind completed");

	//Listen
	listen(socket_desc, 3);

	//Accept and incoming connection
	puts("Waiting for incoming connections...");
	c = sizeof(struct sockaddr_in);

	new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *) & c);

	fflush(stdout);

	if (new_socket < 0)
	{
		perror("Accept Failed");
		return 1;
	}
	else
		puts("Connection accepted");

	for (int i=0; i<3; i++)
		if (!SendFile(new_socket, file[i]))
		{
			printf ("Client required tx abort!\n");
			break;
		}
		
	//Tell client that transfer is finished sending a file len=0
	FILEDATA fd = {0};
	send(new_socket, (void *)&fd, sizeof(fd), 0);

	close(new_socket);
	close(socket_desc);
	fflush(stdout);
	return 0;
}


The Client:
C++
	#ifdef __linux__
	#define _FILE_OFFSET_BITS 64
	#else
	#include <winsock2.h>
	#endif

	#include <stdio.h>
	#include <stdlib.h>
	#include <errno.h>
	#ifdef __linux__
	#include <unistd.h>
	#include <string.h>
	#include <sys/socket.h>
	#include <sys/ioctl.h>
	#include <netinet/in.h>
	#include <arpa/inet.h>
	#define WINBIN
	#else
	#define WINBIN "b"
	#define close closesocket
	#define ftell _ftell64
	#define ioctl ioctlsocket
	typedef int socklen_t;
	#endif
	#include "preamble.h"

/*
 * This function is to be used once we have confirmed that an fp
 * is to be sent.
 * It should read and output a file.
 */
int ReceiveFile(int socket)
{

	long int buffersize = 0;
	long int read_size;
	long long int recv_size = 0;

	FILE *fp;
	FILEDATA fd;

	//Find the size of the fp
	recv(socket, (void *)&fd, sizeof(fd), 0);

	//Make sure that the size is bigger than 0
	if (fd.llSize <= 0)
	{
		printf("End of transfer or error (len=0)\n");
		return 0;
	}

	fp = fopen(fd.FileName, "w" WINBIN);

	if (fp == NULL)
	{
		printf("Error! Cannot create file \"%s\".\n", fd.FileName);
		//Send failure to server
		send(socket, "ABORT", 6, 0);
		return 0;
	}

	printf ("Receiving %lld bytes for file \"%s\".\n", fd.llSize, fd.FileName);
	
	//Send our verification signal
	send(socket, "OK", 3, 0);

	//Loop while we have not received the entire file yet

	while (recv_size < fd.llSize)
	{
		ioctl(socket, FIONREAD, (unsigned long int *)&buffersize);

		//We check to see if there is data to be read from the socket 
		if (buffersize <= 0)
			continue;

		//The protocol put all data together :(
		//If more data of required is available
		//just peek what we need.
		if (buffersize > (fd.llSize - recv_size))
			buffersize = fd.llSize - recv_size;

		char *pBuf = malloc(buffersize);
		if (!pBuf)
		{
			fprintf(stderr, "\nMemory Error. Cannot allocate!\n");
			exit(-1);
		}

		read_size = recv(socket, pBuf, buffersize, 0);
		if (read_size  < 0)
		{
			printf("\n%s", strerror(errno));
			return 0;
		}

		//Write the currently read data into our fp file
		fwrite(pBuf, 1, buffersize, fp);

		free(pBuf);

		//Increment the total number of bytes read
		recv_size += read_size;
		
		printf("\rReceived %lli bytes out of %lli.", recv_size, fd.llSize);
	}

	fclose(fp);
	printf("\nFile successfully Received! \n");
	return 1;
}

int main(int argc, char *argv[])
{
	long long int socket_desc;
	struct sockaddr_in server;

	//printmonth(11, 2015, 30);
	//exit(0);

 #if defined(__WIN32__) || defined(_WIN32)
    //----------------------
    // Declare and initialize variables.
    int iResult;
    WSADATA wsaData;

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR)
	{
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }
 #endif

	//Create socket
	socket_desc = socket(AF_INET, SOCK_STREAM, 0);

	if (socket_desc == -1)
	{
		printf("Could not create socket \n");
	}

	memset(&server, 0, sizeof(server));
	//server.sin_addr.s_addr = inet_addr("10.170.0.40");
	server.sin_addr.s_addr = inet_addr("127.0.0.1");
	server.sin_family = AF_INET;
	server.sin_port = htons(6888);

	//Connect to remote server
	if (connect(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0)
	{
		// printf(strerror(errno));
		close(socket_desc);
		printf("Connect Error \n");
		return -1;
	}

	puts("Connected \n");

	while (ReceiveFile(socket_desc))
		;

	close(socket_desc);

	return 0;
}
 
Share this answer
 
v4
Comments
venkat28vk 18-May-15 3:10am    
The problem is when android is sending a file below 1 MB i am not able to receive the file, and the received file size is zero, But if the file size is above 1MB i am able to receive the file with data loss(mismatch in bytes). How to overcome this.
venkat28vk 27-Jul-15 7:26am    
Hi Frank,

I need your guidance for another time. This time it involves, C has to send a file to java and java has to accept the file and it should revert the same file to C. The fact is i am able to receive the file, but there is no data in it. Kindly assist me in resolving this issue.

I have given the code in the following link,

http://www.codeproject.com/Questions/1010219/How-To-Send-Data-From-C-To-Android-Using-Tcp-Ip-An?arn=0
venkat28vk 5-Aug-15 5:45am    
Hi Frank, can you lend me help for the above problem, because i am facing lot of difficulties and i am able to receive text file with few characters and null data. Give me your valuable suggestions for this.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900