send file through across socket

This is a discussion on send file through across socket within the C++ Programming forums, part of the General Programming Boards category; I want to read a file on the client side and receive the file on the server side. below is ...

  1. #1
    tony kitsch
    Join Date
    Aug 2005
    Posts
    9

    send file through across socket

    I want to read a file on the client side and receive the file on the server side. below is the code i have developed

    Please note that i am using winsock version 1.1

    Code:
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char wait;
    	do
    	{
    		cout << "Enter 1 for Server or 2 for Client: ";
    		cin >> x;
            if(x==2)
    		{
    			do
                {
    				WinMain(NULL, NULL, NULL, NULL);
    				cout << "\nDo you want to send more data(Y/N): ";
    				cin >> wait;
    			}while(wait == 'Y' || wait =='y');
    		}
    
    		else
    		{
    			do
    			{
    				WinMain(NULL, NULL, NULL, NULL);
    				cout << "\nDo you want to continue receiving data: ";
    				cin >> wait;
    			}while(wait == 'Y' || wait == 'y');
    		}
    		cout << "\nDo you want to continue using this program(Y/N): ";
    		cin >> wait;
    	}while(wait == 'Y' || wait =='y');
    	return 0;
    }
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmd, int nShow) {
       /////////////////////////Client/////////////////////////////
       if(x==2)
       {	
       WORD sockVersion;
       WSADATA wsaData;
       int y;
       int z;
       string ip;
       sockVersion = MAKEWORD(1, 1);
       WSAStartup(sockVersion, &wsaData); // Initialize Winsock as before
       LPHOSTENT hostEntry; // Store information about the server
       char text;
       in_addr iaHost;
       cout << "Enter IP address: 192.168.10."; //port address of computer we are sending data to
       do
       {
    	   z=0;
    	   cin >> ip;
    	   if(ip == "20")
    		   iaHost.s_addr = inet_addr("192.168.10.20");
    	   else if(ip == "21")
    		   iaHost.s_addr = inet_addr("192.168.10.21");
    	   else if(ip == "22")
    		   iaHost.s_addr = inet_addr("192.168.10.22");
    	   else
    	   {
    		   cout << "Incorrect IP address!\n";
    		   cout << "Enter IP address: 192.168.10.";
    		   z = 1;
    	   }
       }while(z==1);
       hostEntry = gethostbyaddr((const char*)&iaHost, sizeof(struct in_addr), AF_INET);
       if (!hostEntry) 
       {
          y = WSAGetLastError();
          ReportError(y, "gethostbyaddr()"); // Report the error as before
          WSACleanup();
          return NETWORK_ERROR;
       }
       SOCKET theSocket; // Create the socket
       theSocket = socket(AF_INET, // Go over TCP/IP
                          SOCK_STREAM, // This is a stream-oriented socket
                          IPPROTO_TCP); // Use TCP rather than UDP
       if (theSocket == INVALID_SOCKET) {
          y = WSAGetLastError();
          ReportError(y, "socket()");
          WSACleanup();
          return NETWORK_ERROR;
       }
       SOCKADDR_IN serverInfo; // Fill a SOCKADDR_IN struct with address information
       serverInfo.sin_family = AF_INET;
       serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);		
       serverInfo.sin_port = htons(8888);																							
       y = connect(theSocket, // Connect to the server 
                      (LPSOCKADDR)&serverInfo,
                      sizeof(struct sockaddr));            
       if (y == SOCKET_ERROR) {
          y = WSAGetLastError();
          ReportError(1, "connect()");
          WSACleanup();
          return NETWORK_ERROR;
       }
       fstream inFile;
       cout << "\nEnter the name of the file you would like to read from: ";
       char filename[30];
       cin.ignore();
       cin.getline(filename,30);
       inFile.open(filename, ios::in | ios::binary );
    
    
       char w[256];
       //cout << "\nIR camera information to be sent:  ";
       char *buffer;
       //cin.ignore();
       inFile.getline(w,256);
       buffer = (char*)w;
    	y = send(theSocket, buffer, strlen(buffer), 0);
    	if (y == SOCKET_ERROR) {
    		return NETWORK_ERROR;
    	} 
    	else
       closesocket(theSocket); // Send/receive, then cleanup:
       WSACleanup();
    }
    
    
       /////////////////////////////////server///////////////
    
    else
    {
       WORD sockVersion;
       WSADATA wsaData;
       int y;
       sockVersion = MAKEWORD(1, 1); // We'd like Winsock version 1.1
       WSAStartup(sockVersion, &wsaData); // We begin by initializing Winsock
       SOCKET listeningSocket; // Next, create the listening socket
       listeningSocket = socket(AF_INET, // Go over TCP/IP
                                SOCK_STREAM, // This is a stream-oriented socket
                                IPPROTO_TCP); // Use TCP rather than UDP
       if (listeningSocket == INVALID_SOCKET) {
          y = WSAGetLastError(); // Get a more detailed error
          ReportError(y, "socket()"); // Report the error with our custom function
          WSACleanup(); // Shutdown Winsock
          return NETWORK_ERROR; // Return an error value
       }
       SOCKADDR_IN serverInfo; // Use a SOCKADDR_IN struct to fill in address information
       serverInfo.sin_family = AF_INET;
       serverInfo.sin_addr.s_addr = INADDR_ANY;   // Since this socket is listening for connections, any local address will do
       serverInfo.sin_port = htons(8888);         // Convert integer 8888 to network-byte order and insert into the port field
       y = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr)); // Bind the socket to our local server address
       if (y == SOCKET_ERROR) {
          y = WSAGetLastError();
          ReportError(y, "bind()");
          WSACleanup();
          return NETWORK_ERROR;
       }
       // Make the socket listen
       y = listen(listeningSocket, 10); // Up to 10 connections may wait at any one time to be accept()'ed                                    
       if (y == SOCKET_ERROR) {
          y = WSAGetLastError();
          ReportError(y, "listen()");
          WSACleanup();
          return NETWORK_ERROR;
       }
       SOCKET theClient; // Wait for a client
       cout << "Waiting for a client.......\n";
       theClient = accept(listeningSocket,
                          NULL, // Address of a sockaddr structure (see explanation below)
                          NULL); // Address of a variable containing size of sockaddr struct            
       if (theClient == INVALID_SOCKET) {
          y = WSAGetLastError();
          ReportError(y, "accept()");
          WSACleanup();
          return NETWORK_ERROR;
       }
    
    
    
    
       fstream outFile;
       outFile.open("tony.tony", ios::out | ios::binary );
    
    
    	int i;
    	char wait;
    	char *bufferq = new char[256];
    	for(i = 0; i < 256; i++)
    		bufferq[i] = '!';
    	y = recv(theClient, bufferq, strlen(bufferq), 0);
    	for(i = 0; i < 256; i++)
    	{
    		if (bufferq[i] == '!')
    		break;
    	cout << bufferq[i];
    	outFile << bufferq[i];
    	}
    if(y == SOCKET_ERROR){
    		return NETWORK_ERROR;
    	}else{
    	}
       closesocket(theClient); // Send and receive from the client, and finally,
       closesocket(listeningSocket);
       WSACleanup(); // Shutdown Winsock
       return NETWORK_OK;
    }
    }

    I am able to transmit text files with no problem but when i try to send any other type of file (like a jpeg) the data on the receive side does not match the original file data at all. What can i do differently.

  2. #2
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    You've a couple of problems on your hands. First, your client is using getline() to read from a binary file; if the binary data contains a byte equivalent to the ASCII code for a line break, it will stop reading. Second, your client is only reading a single line of text up to a maximum of only 256 bytes regardless of the actual size of the file. Third, you're only terminating your recv()'d data with an exclamation, so if there happens to be an exclamation in the transmitted data, you'll lose data. Fourth, you are only receiving a maximum of 256 bytes, but your files are likely much larger.

  3. #3
    tony kitsch
    Join Date
    Aug 2005
    Posts
    9
    Sorry, i posted an old version of my code.

    I am using the get() function and i have altered the code to loop therefore i can copy any size of data. What i am having a problem with is the send() and recv() function becuse the data that is sent over the send() and received through the recv() look completely different from one another. I want a function that is similar to the recv() and send() functions but uses char instead of char*.


    Thank you very much

  4. #4
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Post your updated code, including only the portions handling network sending and receiving. You are saying you want to send a char at a time instead of a char*? You can send a single char at a time if you're really desperate to, but that is a terrible practice because you would be transmitting entire frames (including all their overhead) across the network just for a single byte. [sarcasm]Why don't you just send one bit at a time or better yet write down each bit value on a piece of paper at home, walk it across the globe to the destination, walk back home with a receipt, then walk back with the next bit, and so on?[/sarcasm] I'm sure you'll realize that's simply not a very appealing solution to your problem.

  5. #5
    tony kitsch
    Join Date
    Aug 2005
    Posts
    9
    My function does not send one byte at a time across the socket. I read a character at a time from the file and store it in a char array. Once i fill the char array I send it to the send_data() function which sends the data to the recv_data() function. My program works perfectly for regular text files but not for other file types ( like jpeg or avi ).

    The specs require that i send a max of 45 bytes at a time. therefore it takes a while for large files to get transfered. Let me know if there is a faster way to copy files.

    send_data() function:
    Code:
    int send_data(string ip, char data[45]) {
        
    	WORD sockVersion;
        
    	WSADATA wsaData;
        
    	int y;
        
    	int z;
        
    	sockVersion = MAKEWORD(1, 1);
        
    	WSAStartup(sockVersion, &wsaData); // Initialize Winsock as before
        
    	LPHOSTENT hostEntry; // Store information about the server
        
    	char text;
        
    	in_addr iaHost;
    
    	if(ip == "20")
            iaHost.s_addr = inet_addr("192.168.10.20");
    	else if(ip == "21")
    		iaHost.s_addr = inet_addr("192.168.10.21");
    	else if(ip == "22")
    		iaHost.s_addr = inet_addr("192.168.10.22");
    	else if(ip == "00")
    		iaHost.s_addr = inet_addr("127.0.0.1");
    
    	hostEntry = gethostbyaddr((const char*)&iaHost, sizeof(struct in_addr), AF_INET);
    	
    	if (!hostEntry)
    	{
            y = WSAGetLastError();
    		ReportError(y, "gethostbyaddr()"); // Report the error as before
    		WSACleanup();
    		cout << "oops";
    		return NETWORK_ERROR;
    
    		
    	}
    	SOCKET theSocket; // Create the socket
    	
    	theSocket = socket(AF_INET, // Go over TCP/IP
                          SOCK_STREAM, // This is a stream-oriented socket
                          IPPROTO_TCP); // Use TCP rather than UDP
    	
    	if (theSocket == INVALID_SOCKET)
    	{
    
    		y = WSAGetLastError();
    		
    		ReportError(y, "socket()");
    		
    		WSACleanup();
    
    		return NETWORK_ERROR;
    
    	}
    
    	
    	SOCKADDR_IN serverInfo; // Fill a SOCKADDR_IN struct with address information
       
    	serverInfo.sin_family = AF_INET;
       
    	serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);		
       
    	serverInfo.sin_port = htons(8888);																							
       
    	y = connect(theSocket, // Connect to the server 
        
    		(LPSOCKADDR)&serverInfo,
    
    		sizeof(struct sockaddr));            
    
    	if (y == SOCKET_ERROR) 
    	{
    
    		y = WSAGetLastError();
    
    		ReportError(1, "connect()");
    
    		WSACleanup();
    
    		return NETWORK_ERROR;
    
    	}
    
    	char *buffer;
    
    	buffer = (char*)data;
    
    	//fstream test;
    	//test.open("1.bmp", ios::out|ios::binary|ios::app);
    
    
    	int i;
    	for(i = 0; i < 45; i++)
    	//test<<buffer[i];
    	//test.close();
    
    		
    
    	y = send(theSocket, buffer, strlen(buffer), 0);
    	//modified Tim
    //	y = send(theSocket, buffer, 600, 0);
    	
    	if (y == SOCKET_ERROR) 
    	{
    	
    		return NETWORK_ERROR;
    
    	} 
    
    	else
    
    		closesocket(theSocket); // Send/receive, then cleanup:
    
    	WSACleanup();
    
    }
    recv_data() function:
    Code:
    char* receive_data()
    {
    
        WORD sockVersion;
    	WSADATA wsaData;
    	int y;
    	sockVersion = MAKEWORD(1, 1); // We'd like Winsock version 1.1
    	WSAStartup(sockVersion, &wsaData); // We begin by initializing Winsock
    	SOCKET listeningSocket; // Next, create the listening socket
    	listeningSocket = socket(AF_INET, // Go over TCP/IP
                                SOCK_STREAM, // This is a stream-oriented socket
                                IPPROTO_TCP); // Use TCP rather than UDP
    	if (listeningSocket == INVALID_SOCKET)
    	{
    	
    		y = WSAGetLastError(); // Get a more detailed error
    
    		ReportError(y, "socket()"); // Report the error with our custom function
    
    		WSACleanup(); // Shutdown Winsock
    
    		//return NETWORK_ERROR; // Return an error value
    
    	}
    
    	SOCKADDR_IN serverInfo; // Use a SOCKADDR_IN struct to fill in address information
    
    	serverInfo.sin_family = AF_INET;
    
    	serverInfo.sin_addr.s_addr = INADDR_ANY;   // Since this socket is listening for connections, any local address will do
    
    	serverInfo.sin_port = htons(8888);         // Convert integer 8888 to network-byte order and insert into the port field
    
    	y = bind(listeningSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr)); // Bind the socket to our local server address
       
    	if (y == SOCKET_ERROR) 
    	{
        
    		y = WSAGetLastError();
    
    		ReportError(y, "bind()");
    
    		WSACleanup();
    
    		//return NETWORK_ERROR;
    
    	}
    
    	// Make the socket listen
    
    	y = listen(listeningSocket, 10); // Up to 10 connections may wait at any one time to be accept()'ed                                    
    
    	if (y == SOCKET_ERROR) {
    
    		y = WSAGetLastError();
    
    		ReportError(y, "listen()");
    
    		WSACleanup();
    
    		//return NETWORK_ERROR;
    
    	}
    
    	SOCKET theClient; // Wait for a client
    
        theClient = accept(listeningSocket,
                          NULL, // Address of a sockaddr structure (see explanation below)
                          NULL); // Address of a variable containing size of sockaddr struct            
    
    	if (theClient == INVALID_SOCKET) {
    
    		y = WSAGetLastError();
    
    		ReportError(y, "accept()");
    
    		WSACleanup();
    
    		//return NETWORK_ERROR;
    
    	}
    
    	int i;
    	
    	char wait;
    	
    	char *bufferq = new char[45];
    	
    	for(i = 0; i < 45; i++)
    	
    		bufferq[i] = '!';
    
    	y = recv(theClient, bufferq, 45, 0);
    
    	//test code
        
    	/*fstream myfile;
    	myfile.open("right_after_data_is_received.jpeg", ios::out | ios::app | ios::binary);
    	for(int counts=0;counts<45;counts++)
    		myfile << bufferq[counts];*/
    
    	if(y == SOCKET_ERROR){
    	
    		//return NETWORK_ERROR;
    
    	}/*else{
    
    	}*/
    
    	closesocket(theClient); // Send and receive from the client, and finally,
    
    	closesocket(listeningSocket);
    
    	WSACleanup(); // Shutdown Winsock
    
    	//return NETWORK_OK;
    
    	return bufferq;
    }
    I know that this may not be the smartest way to use winsock but i basically know nothing about it. I am using winsock version 1.1 and c++ but i do have some basic c code in there that i got from a friend. I think that i may be able to solve my problem a lot faster if i had c#.

    I use the filename.get() function to read the data form the file a character at a time.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 01:44 PM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 01:36 PM
  3. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 04:44 PM
  4. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 11:12 PM
  5. Need a suggestion on a school project..
    By Screwz Luse in forum C Programming
    Replies: 5
    Last Post: 11-27-2001, 02:58 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21