# Sending file over TCP in C programming language



## gnjepar (Apr 19, 2010)

Hi alls,

I have a problem with sending a file over TCP socket. I want to use sendfile() because it seems to be the quickest (easiest) way. Currently my "server" can send files smaller than N bytes because my send_buffer is N bytes big. It works fine with verry small files, but I want to send files of few Mega Bytes not few Bytes, and even larger, without having to thing about it's size.

server works like this: fread() -> send_buffer -> send()

client (not yet implemented, I use netcat instead): nc ip_addr port > test1


```
while(!feof(file)) {
char filebuffer[N];
fread (filebuffer, sizeof(char), N, file);
send (sockfd, filebuffer, (sizeof (char) * N), 0);
}
```

When I put these in while() I receive file but it has a tail filled with "@" signs (when i read it with vi editor). This is why I need to use sendfile() - it's much simpler, but I don't know how :r

PLEASE HELP
THANKS IN ADVANCE :e


----------



## expl (Apr 20, 2010)

You get trashed tail because you send full buffer and not exactly the amount fread writes into your buffer. You need to check the return value of fread and send only that much.


----------



## gnjepar (Apr 20, 2010)

```
while(!feof(file)) {
char filebuffer[N];
int wasRead = fread (filebuffer, sizeof(char), N, file);
send (sockfd, filebuffer, (sizeof (char) * wasRead), 0);
}
```

I added wasRead integer and now it works fine. Thank you for your advice.

I have another problem, it's related to getopt() function.
Usage of my client program is:

[CMD="tcpclient [-p port] server_IP_addr"][/CMD]

How do i do this with getopt()? I know how to do it without "server_IP_addr", it's like this:

```
argchk = getopt (argc, argv, "p:"))
switch (argchk) {
case 'p': some commands
default: some commands
```

How do I add "server_IP_addr" in these options??

THANKS


----------



## gnjepar (Apr 20, 2010)

I can't edit my posts so...

Usage of my client program is:

tcpclient [-p port] server_IP_addr


----------



## expl (Apr 20, 2010)

Simplest way to do this would be to add:

```
if(argc != 1 && argc != 3){ /*ignore if no arguments are passed or if only -p port is passed*/
   server_ip = argv[argc - 1];
}
```

You can do this after or before getopt(), it will ignore all arguments without "-" at start unless its defined as key's value like you did for the "-p".


----------



## gnjepar (Apr 20, 2010)

That is preety simple, thank you. Though it would be nice to know getopt() way if anybody knows it.


----------



## jotawski (Apr 21, 2010)

gnjepar said:
			
		

> ```
> while(!feof(file)) {
> char filebuffer[N];
> int wasRead = fread (filebuffer, sizeof(char), N, file);
> ...



hi,

why do we not check for wasRead for return code from fread too.

just wonder.


----------



## gnjepar (Apr 21, 2010)

This is the final version:


```
while(!feof(file)) {

		char filebuffer[FILE_SIZE];
		int procitano = fread (filebuffer, sizeof (char), FILE_SIZE, file);
		if (procitano < 0) errx (-1, "fread()");
		senddatacount = send (rcvsock, filebuffer, (sizeof (char)) * procitano, 0);
		if (senddatacount < 0) errx (-1, "send()");
		
	}
```

I do check return value of recv() but it wasn't important for solving my problem so I didn't write it before. :stud


----------



## gnjepar (Apr 23, 2010)

If anybody want's to I can post here my code.


----------



## psycho (Apr 23, 2010)

I want, pls post.

p.s. pozdrav iz BiH


----------



## gnjepar (Aug 13, 2011)

Just saw this thread by accident. Sorry about not posting my code, I am not allowed to do so by my profesor. Wanted to post this earlier but I forgot.


----------

