Thread: Help with coding/command sending Jpg files through sockets

  1. #1
    Registered User
    Join Date
    Jan 2012
    Posts
    37

    Help with coding/command sending Jpg files through sockets

    Hello everyone,
    I am having some troubles with my code: server and client.
    What my code does it takes a jpeg picture (lets say located on my ubuntu desktop) and sends it to the client where it creates a new jpeg, "test.jpeg". However I am having difficulty with my coding or the commends to have this done. I am new to writing network code so help is really appreciated.

    Code:
    
    
    Code:
    ------------server.cpp---------------
    #include "serverInit.h"#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>//for sleep()#include <iostream>using std::cout;using std::endl;using std::fstream;using std::ios;#define MAX_PATH 256void dostuff(int); /* function prototype *///int UploadFile(char* PathofFile);void error(const char *msg){ perror(msg); exit(1);}int main(int argc, char *argv[]){ char PathofFile[MAX_PATH]; int sConnect, sListen, portno, pid; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; if (argc < 2) { cout << "ERROR, no port provided" << endl; //fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sConnect = socket(AF_INET, SOCK_STREAM, 0); sListen = socket(AF_INET, SOCK_STREAM, 0); if (sConnect < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sListen, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sListen,SOMAXCONN);//5); clilen = sizeof(cli_addr); for(;; sleep(250)) { if(sConnect = accept(sListen, (struct sockaddr *) &cli_addr, &clilen)) { cout << "Connection Established!" << endl; gets(PathofFile); UploadFile(PathofFile); } } return 0;}//End of Main------serverInit.h---------#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <fstream>#include <iostream>using std::cout;using std::endl;using std::ifstream;int sConnect, sListen;using std::ios;int UploadFile(char* PathofFile){ char* buffer; int size; ifstream file; file.open(PathofFile, ios::in | ios::binary | ios::ate); if(file.is_open()) { file.seekg(0, ios::end); size = file.tellg(); file.seekg(0, ios::beg); buffer = new char[size]; file.read(buffer, size); send(sConnect, buffer, size, 0); file.close(); }return 0;}--------client.cpp-------------#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <unistd.h>//for sleep()#include <iostream>#include <fstream>using std::ofstream;using std::cout;using std::endl;using std::ios;void error(const char *msg){ perror(msg); exit(0);}int main(int argc, char *argv[]){ int sConnect, portno, n; int WS, errorCode; char buffer[1000000]; struct sockaddr_in serv_addr; struct hostent *server; //char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sConnect = socket(AF_INET, SOCK_STREAM, 0); if (sConnect < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { cout << "ERROR, no such host" << endl; exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); for(;; sleep(250)){ if (connect(sConnect,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); if(errorCode != -1){//SOCKET_ERROR){ WS = recv(sConnect, buffer, sizeof(buffer), 0); ofstream file; file.open("test.jpeg", ios::out | ios::binary | ios::ate); file.write(buffer, sizeof(buffer)); file.close(); } }return 0;}//End of Main

  2. #2
    Registered User
    Join Date
    Jan 2012
    Posts
    37
    Code:
    ------------server.cpp---------------
    #include "serverInit.h"
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>//for sleep()
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::fstream;
    using std::ios;
    #define MAX_PATH 256
    void dostuff(int); /* function prototype */
    //int UploadFile(char* PathofFile);
    void error(const char *msg)
    {    
    perror(msg);    exit(1);
    }
    int main(int argc, char *argv[]){     
    
    char PathofFile[MAX_PATH];     
    int sConnect, sListen, portno, pid;     
    socklen_t clilen;     
    struct sockaddr_in serv_addr, cli_addr;     
    if (argc < 2) {         cout << "ERROR, no port provided" << endl;     //fprintf(stderr,"ERROR, no port provided\n");         exit(1);     
    }    
     sConnect = socket(AF_INET, SOCK_STREAM, 0);     
    sListen = socket(AF_INET, SOCK_STREAM, 0);     
    if (sConnect < 0)        error("ERROR opening socket");    
    bzero((char *) &serv_addr, sizeof(serv_addr));     
    portno = atoi(argv[1]);     
    serv_addr.sin_family = AF_INET;     
    serv_addr.sin_addr.s_addr = INADDR_ANY;     
    serv_addr.sin_port = htons(portno);    
     if (bind(sListen, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)              
    error("ERROR on binding");     
    listen(sListen,SOMAXCONN);//5);     
    clilen = sizeof(cli_addr);    
     for(;; sleep(250))     
    {      if(sConnect = accept(sListen, (struct sockaddr *) &cli_addr, &clilen))   
       {    cout << "Connection Established!" << endl;   
            gets(PathofFile);    
            UploadFile(PathofFile);    
         }     
    }  
    return 0;
    }//End of Main
    ------serverInit.h---------
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fstream>
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::ifstream;
    int sConnect, sListen;
    using std::ios;
    int UploadFile(char* PathofFile){    
    char* buffer;   
     int size;    
    ifstream file;    
    file.open(PathofFile, ios::in | ios::binary | ios::ate);  
      if(file.is_open())    {    
    file.seekg(0, ios::end);    
    size = file.tellg();    
    file.seekg(0, ios::beg);  
      buffer = new char[size];  
      file.read(buffer, size);   
     send(sConnect, buffer, size, 0);   
     file.close();      
      }return 0;
    }
    --------client.cpp-------------
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <unistd.h>//for sleep()
    #include <iostream>
    #include <fstream>
    using std::ofstream;
    using std::cout;
    using std::endl;
    using std::ios;
    void error(const char *msg){  
      perror(msg);    exit(0);}
    int main(int argc, char *argv[]){   
     int sConnect, portno, n;    
    int WS, errorCode;    
    char buffer[1000000];  
      struct sockaddr_in serv_addr;  
      struct hostent *server;    //char buffer[256]; 
       if (argc < 3) {       fprintf(stderr,"usage %s hostname port\n", argv[0]);       exit(0);    }    
    portno = atoi(argv[2]);    
    sConnect = socket(AF_INET, SOCK_STREAM, 0);   
     if (sConnect < 0)         
    error("ERROR opening socket");   
     server = gethostbyname(argv[1]);   
     if (server == NULL) {        cout << "ERROR, no such host" << endl;        exit(0);    }   
     bzero((char *) &serv_addr, sizeof(serv_addr));   
     serv_addr.sin_family = AF_INET;    bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);  
      serv_addr.sin_port = htons(portno);    
    for(;; sleep(250)){           
     if (connect(sConnect,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)         error("ERROR connecting");        
    if(errorCode != -1){//SOCKET_ERROR){    
    WS = recv(sConnect, buffer, sizeof(buffer), 0);    
    ofstream file;        
    file.open("test.jpeg", ios::out | ios::binary | ios::ate);  
      file.write(buffer, sizeof(buffer));    
    file.close();       
     }    
    }return 0;}//End of Main
    Last edited by geewhan; 01-20-2012 at 08:07 PM.

  3. #3
    Registered User
    Join Date
    Jan 2012
    Posts
    37
    how do i show my code properly. I am new to this forum

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You should use "copy as text" or "paste as text" as appropriate to your IDE or Browser.

    Your last attempt was OK (for the board).
    But you need to work on the indentation if you want humans to look at your code in detail
    Read this -> SourceForge.net: Indentation - cpwiki

    > file.write(buffer, sizeof(buffer));
    Are all your files the same size?
    How about using the result for the number of bytes received?

    Also, there is NO guarantee that if you send() 100K in a single buffer that you'll also recv() 100K in a single buffer. Fragmentation can happen at both ends, and you need to allow for this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Jan 2012
    Posts
    37
    Quote Originally Posted by Salem View Post
    You should use "copy as text" or "paste as text" as appropriate to your IDE or Browser.

    > file.write(buffer, sizeof(buffer));
    Are all your files the same size?
    How about using the result for the number of bytes received?

    Also, there is NO guarantee that if you send() 100K in a single buffer that you'll also recv() 100K in a single buffer. Fragmentation can happen at both ends, and you need to allow for this.

    I am not sure why you are pointing out the file.write().
    I am just sending a simple jpg file. Its size is like 757KB

    I also see that you pointed 100k, I am not sure where you got that number. I assume you are talking about my buffer size which is 1M, unless I am wrong. But thank you for your help.

    Have you try compiling and running this? I would like to know if this works for anyone else

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I am just sending a simple jpg file. Its size is like 757KB
    So why do you always create a file which is 1MB in size then?

    n = send(sConnect, buffer, size, 0);
    Valid success values for n are 1,2,3,4,5,6 all the way up to size.
    If n is ANYTHING other than size, you need to go round and send the trailing data.
    Code:
    char buff[SIZE]; // the buffer you want to send
    
    // keep sending bits of buffer until it's all gone.
    ssize_t n, remaining = SIZE;
    char *bp = buff;
    while ( remaining > 0 && (n = send(sConnect, bp, remaining, 0)) > 0 ) {
        bp += n;
        remaining -= n;
    }
    The same with the recv(), you call it in a loop, look at the return result, and deal with exactly 'n' bytes of data.
    Don't assume that a single recv() call is going to wait around for a 1MB buffer to be filled - it just isn't going to happen.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2012
    Posts
    37
    Quote Originally Posted by Salem View Post
    >

    n = send(sConnect, buffer, size, 0);
    Valid success values for n are 1,2,3,4,5,6 all the way up to size.
    If n is ANYTHING other than size, you need to go round and send the trailing data.
    Code:
    char buff[SIZE]; // the buffer you want to send
    
    // keep sending bits of buffer until it's all gone.
    ssize_t n, remaining = SIZE;
    char *bp = buff;
    while ( remaining > 0 && (n = send(sConnect, bp, remaining, 0)) > 0 ) {
        bp += n;
        remaining -= n;
    }
    The same with the recv(), you call it in a loop, look at the return result, and deal with exactly 'n' bytes of data.
    Don't assume that a single recv() call is going to wait around for a 1MB buffer to be filled - it just isn't going to happen.
    I have compiled and ran the new code that you have suggested. However there is a problem where once I run the client code the test.jpeg pops up. Which is not what I want because I haven't given any jpeg to send it through first.

    If I may explain how I am running the terminals. I have two terminals: one for client and one for server.

    server terminal commands:
    g++ server.cpp
    ./a.out 2222
    (waits for the client)

    client terminal commands:
    g++ client.cpp
    ./a.out 127.0.0.1 2222

    server terminals commands:
    prints out: "Connected Established!"

    In the client folder the test.jpeg pops out of no where, which
    I do not want to happen until I have given a jpeg file.

    I am trying to figure out how to stop this random pop out and how to send a jpeg file to the client folder.

    Thanks


    Code:
    //------------server.cpp--------------- #include "serverInit.h" #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h>//for sleep() #include <iostream> using std::cout; using std::endl; using std::fstream; using std::ios; #define MAX_PATH 256 void dostuff(int); /* function prototype */ //int UploadFile(char* PathofFile); void error(const char *msg) { perror(msg); exit(1); } int main(int argc, char *argv[]){ char PathofFile[MAX_PATH]; int sConnect, sListen, portno, pid; socklen_t clilen; struct sockaddr_in serv_addr, cli_addr; if (argc < 2) { cout << "ERROR, no port provided" << endl; //fprintf(stderr,"ERROR, no port provided\n"); exit(1); } sConnect = socket(AF_INET, SOCK_STREAM, 0); sListen = socket(AF_INET, SOCK_STREAM, 0); if (sConnect < 0) error("ERROR opening socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sListen, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); listen(sListen,SOMAXCONN);//5); clilen = sizeof(cli_addr); for(;; sleep(250)){ if(sConnect = accept(sListen, (struct sockaddr *) &cli_addr, &clilen)) { cout << "Connection Established!" << endl; gets(PathofFile); UploadFile(PathofFile); } } return 0; }//End of Main //------serverInit.h--------- #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <fstream> #include <iostream> using std::cout; using std::endl; using std::ifstream; int sConnect, sListen; using std::ios; int UploadFile(char* PathofFile){ char* buffer; int size; ifstream file; file.open(PathofFile, ios::in | ios::binary | ios::ate); if(file.is_open()) { file.seekg(0, ios::end); size = file.tellg(); file.seekg(0, ios::beg); buffer = new char[size]; file.read(buffer, size); //send(sConnect, buffer, size, 0); char buff[size]; // the buffer you want to send // keep sending bits of buffer until it's all gone. ssize_t n, remaining = size; char *bp = buff; while ( remaining > 0 && (n = send(sConnect, bp, remaining, 0)) > 0 ) { bp += n; remaining -= n; } file.close(); }return 0; } //--------client.cpp------------- #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <unistd.h>//for sleep() #include <iostream> #include <fstream> using std::ofstream; using std::cout; using std::endl; using std::ios; void error(const char *msg){ perror(msg); exit(0);} int main(int argc, char *argv[]){ int sConnect, portno, n; int WS, errorCode; char buffer[1000000]; struct sockaddr_in serv_addr; struct hostent *server; //char buffer[256]; if (argc < 3) { fprintf(stderr,"usage %s hostname port\n", argv[0]); exit(0); } portno = atoi(argv[2]); sConnect = socket(AF_INET, SOCK_STREAM, 0); if (sConnect < 0) error("ERROR opening socket"); server = gethostbyname(argv[1]); if (server == NULL) { cout << "ERROR, no such host" << endl; exit(0); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(portno); for(;; sleep(250)){ if (connect(sConnect,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting"); if(errorCode != -1){//SOCKET_ERROR){ //WS = recv(sConnect, buffer, sizeof(buffer), 0); int SIZE; char buff[SIZE]; // the buffer you want to send // keep sending bits of buffer until it's all gone. ssize_t n, remaining = SIZE; char *bp = buff; while ( remaining > 0 && (n = recv(sConnect, bp, remaining, 0)) > 0 ) { bp += n; remaining -= n; } ofstream file; file.open("test.jpeg", ios::out | ios::binary | ios::ate); file.write(buffer, sizeof(buffer)); file.close(); } }return 0;}//End of Main

  8. #8
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Don't use gets(), and don't ever put function declarations in header files. (remember, prototypes in the header, and declarations in the source). I'd like to help you with other stuff, but please indent your code better. If it was better, you probably wouldn't have missed the obvious reason why it's not sending correctly: nowhere does the upload function get passed the connected socket. It only uses a similarly-named global variable which does nothing. Globals are almost always bad, and this is one of the reasons.

    Also, check out
    > FAQ > Why gets() is bad / Buffer Overflows - Cprogramming.com
    > Global Variables Are Bad

    > In the client folder the test.jpeg pops out of no where
    I haven't completely read your code, but that sounds like you have data pending on the network that your program sucks down as soon as it's launched. It most likely would be originated from previous server runs that send the data, but the client doesn't fully receive it.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    I can see that you simply copy/pasted without thinking about it.

    Also, you're still pasting code full of whatever formatting your IDE cares to add. Look at my post #5 and compare it to the stuff you posted (font, indentation etc).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sending a file across sockets.
    By mushy in forum C Programming
    Replies: 23
    Last Post: 10-05-2010, 10:02 AM
  2. Need help with sending an int via sockets.
    By pheeze in forum C Programming
    Replies: 5
    Last Post: 11-10-2009, 02:03 PM
  3. Sending two files in one command?
    By Mankthetank19 in forum C Programming
    Replies: 13
    Last Post: 12-11-2008, 04:13 PM
  4. Sending Hex to sockets?
    By chrisjmoss in forum Networking/Device Communication
    Replies: 1
    Last Post: 04-03-2008, 05:50 AM