LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   send a file through raw socket using C programming (https://www.linuxquestions.org/questions/programming-9/send-a-file-through-raw-socket-using-c-programming-821751/)

enginius 07-23-2010 01:26 PM

send a file through raw socket using C programming
 
Hi all,

I am currently doing a research on video transmission over wireless LAN. I tend to transmit my offline file (xx.svc) from server to client.It may sound stupid (since I have a very little knowledge about c programming and raw socket), but my biggest challenges is that when I want to write the file to the buffer, how actually to define/include the file at the programming coding? where I need to locate the file? Is it at the same folder with my c programming, or somewhere in the linux\include folder?

Can anyone just give a simple example on how to include a file and write it into a buffer before send it through raw socket.

Thanks in advance.

Nique

yaami 07-23-2010 01:40 PM

Hi,

This link http://www.linuxhowtos.org/C_C++/socket.htm provides a good intro to sockets in Linux. provides source code to send/receive a message. So you can make changes to fit to your use. Hope this helps.

jf.argentino 07-23-2010 02:51 PM

Quote:

Can anyone just give a simple example on how to include a file and write it into a buffer before send it through raw socket.
Another good resource for socket programming is the beej's tutorial
For the file "problem", do you really think that you need to know the file path when coding your app? If so, how a text editor (for example) could work ?!?
You need to open your file given its path with "fopen"; read it chunk by chunk with "fread", and send each chunk of data through you socket. Close the file once done with "fclose". See manuals for more details (in a console, "man fopen", "man fread"...

But, especially if you're a beginner, don't reinvent the wheel, take a look to project like "ortp", "videolan server" etc...

enginius 07-25-2010 07:12 AM

thanks Yaami and Argentino for your help. I have gone through the link provided and also beej`s guideline which have become my primary reference since before. However, my question is that, when we want to read/open the specific file,let say xx.264,I could not see any link to specific folder or define to a specific file in order to read/open the file. For an example;

int SendRawPacket(int rawsock, unsigned char *pkt, int pkt_len)
{
int sent= 0;

/* A simple write on the socket ..thats all it takes ! */

if((sent = write(rawsock, pkt, pkt_len)) != pkt_len)
{
/* Error */
printf("Could only send %d bytes of packet of length %d\n", sent, pkt_len);
return 0;
}

return 1;


}


As the pkt is the pointer, where does this pointer refers to?

Thank you

dwhitney67 07-25-2010 09:28 AM

Quote:

Originally Posted by enginius (Post 4044698)
... I could not see any link to specific folder or define to a specific file in order to read/open the file.

Your server and your client have to define a communications protocol. For example, the client could send a message requesting a list of all available files, and then the server would respond with this list. Right there you have two types of messages; these typically are referred to as being part of the IPC, or Interprocess Communication set of messages. Read more here: http://en.wikipedia.org/wiki/Inter-p..._communication

Anyhow, basically what I am attempting to state is that your server and client need to establish some form of protocol in which they exchange information. No matter how you look at it, the information (data) needs to be treated indifferently. In other words, whether it is a text request or data from a file, your applications will send and receive the data in the same manner. It is what you do with the data that matters.

So, here is a scenario:

1. Server is running and awaiting client connections
2. Client is running and establishes connection with server
3. Client sends a request for a listing of all available files (of interest) on the server
4. Server responds by sending a list of file names (including the path)
5. Client sends a request to download a particular file
6. Server receives request
7. Server proceeds to open the file, read it in chunks, and send the data to the client
8. Client receives data and writes it to a file (it already knows the filename from Step 5).

For all of this to transpire, you will need to implement a series of functions on both the server and the client that will handle each appropriate step listed above.

C library functions that come to mind that you will require for the Server:
  • socket()
  • listen()
  • bind()
  • accept()
  • recv()
  • send()
  • opendir()
  • readdir()
  • closedir()
  • fopen()
  • fread()
  • fclose()

For the client:
  • socket()
  • connect()
  • recv()
  • send()
  • fopen()
  • fwrite()
  • fclose()

As for getting assistance with the implementation of the Server and Client, this is not a forum for requesting such. If you cannot accomplish the task yourself, then consult with an experienced software developer, who may or may not charge a fee for their services. If you have software written, that is not working for whatever reason, then feel free to post your code, so that I or someone else can critique it, and help you get over the hurdle that is preventing you from resolving your task.


P.S. Often times people refer to the Berkeley Sockets as "Raw" sockets. These terms are not the same. A raw socket is one in which the Server and/or the Client will take on the onerous task of piecing together each individual component of the TCP or UDP packets, which includes the header, checksums, data, etc. It is very tedious to do, and more importantly it requires root-privileges to open such a socket. For your task, you do not require these raw sockets; a regular socket will do. For example:
Code:

int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
A raw socket would be opened as:
Code:

int sd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);

enginius 07-25-2010 10:26 AM

thanks all, i am currently working on fopen() function.

thanks

faeze kalantari 09-18-2010 05:51 AM

hi enginius
Does your code work finaly? If so, could you give me some parts of it, including openning file and sending.

dwhitney67 09-18-2010 08:36 AM

Quote:

Originally Posted by faeze kalantari (Post 4101564)
hi enginius
Does your code work finaly? If so, could you give me some parts of it, including openning file and sending.

This is not a homework forum; for that, consult with your teacher.

xixonga 11-27-2010 07:50 PM

hi,

i'm having one annoying trouble doing this client-server file transfer...

i'm using fopen on binary mode...send() and recv() functions...but there's one problem:
i can send images, .pdf's...etc. But i can't send any text files...i mean, i can send them, but the receiver can't open them because the OS doesn't recognize the file as text (character codifying)

any solutions?

jf.argentino 11-28-2010 03:19 AM

Quote:

but the receiver can't open them because the OS doesn't recognize the file as text (character codifying)
So just convert the file into a readable characters encoding with "iconv" command, available in LINUX.

dwhitney67 11-28-2010 08:06 AM

Quote:

Originally Posted by xixonga (Post 4173130)
hi,

i'm having one annoying trouble doing this client-server file transfer...

i'm using fopen on binary mode...send() and recv() functions...but there's one problem:
i can send images, .pdf's...etc. But i can't send any text files...i mean, i can send them, but the receiver can't open them because the OS doesn't recognize the file as text (character codifying)

any solutions?

You might be doing something odd in your code that is preventing to from transferring the data correctly. Can you please check the md5sums of both the source file and the destination file to ensure they are the same? If the sums are not the same, then you definitely have a source code problem.

P.S. Example of using md5sum:
Code:

md5sum /etc/hosts

xixonga 11-28-2010 08:07 AM

Quote:

Originally Posted by jf.argentino (Post 4173318)
So just convert the file into a readable characters encoding with "iconv" command, available in LINUX.

hi,

but i can't do that...i have to guarantee that the receiver gets all the files simple and clean...
what's the right size of chunks to send over "send" function? because i guess if i send a chunk much bigger than the file, there will be garbage on buffer...and the file gets unreadable?!!

dwhitney67 11-28-2010 08:13 AM

Quote:

Originally Posted by xixonga (Post 4173515)
... because i guess if i send a chunk much bigger than the file, there will be garbage on buffer...and the file gets unreadable?!!

Duh! If you are sending more data than you read from a file, then you need to sort that issue out. Send only the number of bytes read from the file. What language are you programming in? In C, the read() function returns the number of bytes successfully read (or an error, should one occur).

xixonga 11-28-2010 08:35 AM

Quote:

Originally Posted by dwhitney67 (Post 4173518)
Duh! If you are sending more data than you read from a file, then you need to sort that issue out. Send only the number of bytes read from the file. What language are you programming in? In C, the read() function returns the number of bytes successfully read (or an error, should one occur).


the "md5sum" command returned different sums in fact:
client:
a3f74fbefb7ed7f149a025874270feae server.txt

server:
4291b47d28a6456c495fbb5646a718dd server.txt


i'm using C...and i'm also using fread to read the files. Heres the send-receive code:
client (uploader)
Code:

FILE* fp = fopen(buffer,"rb");      // buffer = "server.txt"
       
                       
                        printf("uploading...\n");
                          while(!feof(fp)){
                                bzero(buffer,150);
                                  fread(buffer,sizeof(char),150,fp);
                                  send(sockfd,buffer,150,0);
                                    if (n < 0)
                                        error("ERROR writing to socket");
                          }
                          write(sockfd,"quit",150);   
                          fclose(fp);


server (receiver)
Code:

FILE* fp = fopen(buffer,"wb");    // buffer contains the name sent by client: "server.txt"
         
        while(1){
              // bzero(buffer,150);
                recv(sock,buffer,150,0);
                if(strcmp(buffer,"quit")==0)
                {
                        break; 
                }
               
                fwrite(buffer,1,150,fp);
        }
        fclose(fp);


dwhitney67 11-28-2010 08:48 AM

You are not using the return value from fread(). This return value indicates whether you read any data, and if so, how many bytes.

You should be doing something like this for the "uploader":
Code:

char  buffer[1024];
size_t bytes = 0;

while ((bytes = fread(buffer,sizeof(char), sizeof(buffer),fp)) > 0)
{
  send(sockfd, buffer, bytes, 0);
}

Btw, bzero() was deprecated as of POSIX-2001. You do not need to use it, but if you did need similar functionality, you should use memset().

For the receiver:
Code:

char    buffer[1024];
ssize_t bytes = 0;

while ((bytes = recv(sock, buffer, sizeof(buffer), 0)) > 0)
{
  fwrite(buffer, sizeof(char), bytes, fp);
}

P.S. The code above is sorely missing a lot of error checking.


All times are GMT -5. The time now is 02:36 AM.