C socket, send message after file, TCP - c

I want to send file through socket and after that i want to send three messages. This code below works, but i have to send first sentence two times. My question is why? Without one sentence1, receiver display sentence2, sentence3 and sentence3. What is wrong with this code?
I'm using tcp protocol.
Sender.c
char file_size[256];
struct stat file_stat;
int sent_bytes = 0;
int fd;
int offset;
int remain_data;
fd = open(FILE_TO_SEND, O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0)
{
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);
sprintf(file_size, "%d", file_stat.st_size);
write(sck, file_size, 256);
char buffer[1024] = "";
while (1) {
int bytes_read = read(fd, buffer, sizeof(buffer));
if (bytes_read == 0)
break;
void *p = buffer;
while (bytes_read > 0) {
int bytes_written = write(sck, p, bytes_read);
if (bytes_written <= 0) {
// handle errors
}
bytes_read -= bytes_written;
p += bytes_written;
}
}
char sentence[1024];
write(sck, sentence1, 1024);
write(sck, sentence1, 1024);
write(sck, sentence2, 1024);
write(sck, sentence3, 1024);
Receiver.c
char buffer[1024] = "";
int sck = *((int*) arg);
int file_size;
read(sck, buffer, 256);
file_size = atoi(buffer);
ssize_t len;
FILE *received_file;
int remain_data = 0;
received_file = fopen("plik.pdf", "w");
if (received_file == NULL)
{
fprintf(stderr, "Failed to open file foo --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
remain_data = file_size;
while (((len = recv(sck, buffer, 1024, 0)) > 0) && (remain_data > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
}
fclose(received_file);
read (sck, buffer, 1024);
printf("%s 1\n", buffer);
read (sck, buffer, 1024);
printf("%s 2\n", buffer);
read (sck, buffer, 1024);
printf("%s 3\n", buffer);

Nothing to do with TCP protocol. Your logic is flawed. You are receiving the data and then checking for remain_data. So your sentence1 is received and discarded in the while loop.
Move your recv() into the body of while to fix this or change the order in while.
while ((remain_data > 0) && ((len = recv(sck, buffer, 1024, 0)) > 0))
In the modified while, you call recv() only if remain_data > 0. recv() is not called if remain_data == 0 (lazy evaluation). So your while loop ends immediately after receiving the file and ready to receive your sentences. In your code, the while loop read the first sentence, then checked remain_data > 0 effectively discarding sentence1

Related

C: incomplete file transfer through TCP server and client sockets

I am having trouble transferring files through TCP sockets in C. I send the files in little chunks of 8192 bytes from a server to a client. The issue is that the client receives the one before last incompletely and does not receive the last one at all.
Here are both relevant parts of the code.
server:
fd = open(filename,O_RDONLY);
if (fd == -1)
{
fprintf(stderr, "Error opening file --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
/* Get file stats */
if (fstat(fd, &file_stat) < 0)
{
fprintf(stderr, "Error fstat --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "File Size: \n%d bytes\n", file_stat.st_size);
sprintf(file_size, "%d", file_stat.st_size);
/* Sending file size */
len = send(peer_socket, file_size, sizeof(file_size), 0);
if (len < 0)
{
fprintf(stderr, "Error on sending greetings --> %s", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "Server sent %d bytes for the size\n", len);
offset = 0;
remain_data = file_stat.st_size;
/* Sending file data */
while(((sent_bytes = sendfile(peer_socket, fd,&offset, BUFSIZ))>0)&&(remain_data > 0))
{
remain_data -= sent_bytes;
fprintf(stdout, "2. Server sent %d bytes from file's data, offset is now : %d and remaining data = %d\n", sent_bytes, offset, remain_data);
}
and client side:
ecv(client_socket, buffer, BUFSIZ, 0);
file_size = atoi(buffer);
fprintf(stdout, "\nFile size : %d\n", file_size);
//received_file = fclose(fopen(FILENAME, "w"));
received_file = fopen(FILENAME, "w");
if (received_file == NULL)
{
fprintf(stderr, "Failed to open file --> %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
remain_data = file_size;
while ((remain_data > 0)&&((len = recv(client_socket, buffer, BUFSIZ, 0)) > 0))
{
fwrite(buffer, sizeof(char), len, received_file);
remain_data -= len;
//if (remain_data < BUFSIZ)
// buffsize = remain_data;
//bzero(buffer,BUFSIZ);
//if (len == 0 || len != BUFSIZ)
// break;
fprintf(stdout, "Received %d bytes , %d bytes remaining\n", len, remain_data);
}
//code for accelerator here
fclose(received_file);
The output on server side looks like this (which seems to be correct):
But on the client side this is what I get:
From there the applications on both sides are stuck forever. Any idea what might cause the trouble?
Thanks for your answers

c - client server socket programming - sending files

I am having trouble sending and receiving files while working with sockets in C.
Let's say I have a file that is 2,463 bytes big and I want to send it from client to server but it never sends the entire file.
I've been searching the internet for a while now but couldn't find a solution so I'd be very glad if someone could tell me how to make this work.
Here is my code:
Client:
char buffer[256];
bzero(buffer, 256);
int block_size;
while(1){
block_size = fread(buffer, sizeof(char), sizeof(buffer), fs); // read from the file
if (block_size == 0){
break;
}
if (block_size < 0){
perror("ERROR: Failed while sending data.");
exit(EXIT_FAILURE);
break;
}
void *p = buffer;
while (block_size > 0) {
int bytes_written = write(clientSocket, buffer, block_size); // send the data to server
if (bytes_written <= 0) {
perror("ERROR: Failed while sending data.");
exit(EXIT_FAILURE);
}
block_size -= bytes_written;
p += bytes_written;
}
bzero(buffer, 256);
}
Server:
bzero(buffer, 256);
int file_block_size = 0;
while (1){
bzero(buffer, 256);
file_block_size = read(incoming_socket, buffer,255); // read the data from client
fwrite(buffer, sizeof(char), file_block_size, fr); // write the data to file
if (file_block_size == 0 || file_block_size < 256){
fwrite(buffer, sizeof(char), file_block_size, fr);
break;
}
}
As I've said, this never sends the entire file that is for example 2,463 bytes big, only a portion of it.
Thanks in advance, will be glad for any help I can get.
You need to pair your read with a write. As in the current state your client code will send only the result of your last read operation since you are overwriting the contents of your buffer on each read.
Try something like this on the client side:
char buffer[256];
size_t bytes_read = 0;
ssize_t bytes_written = 0;
do{
bytes_read = fread(buffer, sizeof(char), sizeof(buffer), fs);
if(ferror(fs))
{
perror("Error while reading from file.");
close(clientSocket);
fclose(fs);
exit(EXIT_FAILURE);
}
bytes_written = write(clientSocket, buffer, bytes_read);
printf("Write operation status: %s; bytes sent: %d\n", strerror(errno), bytes_written);
} while(!feof(fs) && bytes_written != -1);
And on the server side I would do:
char buffer[256];
ssize_t bytes_read = 0;
while((bytes_read = read(incoming_socket, buffer, sizeof(buffer))) > 0)
{
printf("%d bytes read\n", bytes_read);
fwrite(buffer, sizeof(char), bytes_read, fr);
if(ferror(fr))
{
perror("Error while writing to file");
close(incoming_socket);
fclose(fr);
exit(EXIT_FAILURE);
}
}
if(bytes_read == -1)
printf("%s\n", strerror(errno));

TCP client not handling broken server connect correctly in C

I created my own ftp server/client (a very simple version) using TCP. There are 5 possible commands: ls-remote, ls-local, get , put and exit. Also, I am using multiprocessing in my server code, to be able to handle multiple clients simultaneously by using fork(). Everything is working perfectly except for one thing that I am noticing: I am having a problem handling broken server connect correctly. For example, if something were to go wrong while the server sends a message, I check if the return value from the send call is less than 0, and then I close the socket, and call exit(-1) to terminate the process; however, this causes my client to hang...
my client:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <stdio.h>
void readDirectory();
void syserr(char* msg)
{ perror(msg);
exit(-1);
}
int main(int argc, char* argv[])
{
int sockfd, portno, n;
struct hostent* server;
struct sockaddr_in serv_addr;
char buffer[256], temp[256];
if(argc < 3) {
fprintf(stderr, "Usage: %s <hostname> <port>\n", argv[0]);
return 1;
}
portno = atoi(argv[2]);
server = gethostbyname(argv[1]);
if(!server) {
fprintf(stderr, "ERROR: no such host: %s\n", argv[1]);
return 2;
}
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sockfd < 0) syserr("can't open socket");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr = *((struct in_addr*)server->h_addr);
serv_addr.sin_port = htons(portno);
if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
syserr("can't connect to server");
printf("Connection to %s:%s established. Now awaiting commands...\n\n\n", argv[1], argv[2]);
do{
printf("%s:%s> ", argv[1], argv[2]); //prompt user for command
fgets(buffer, 255, stdin);
n = strlen(buffer);
if(n>0 && buffer[n-1] == '\n')
buffer[n-1] = '\0';
if(strcmp(buffer, "ls-remote") == 0){ //display files from server directory
uint32_t size;
uint32_t commandSize = strlen(buffer);
//convert to network form
commandSize = htonl(commandSize);
n = send(sockfd, &commandSize, sizeof(commandSize), 0); // send size of command to server
if(n < 0) syserr("can't send to server");
n = send(sockfd, buffer, strlen(buffer), 0); // send command to server
if(n < 0) syserr("can't send to server");
n = recv(sockfd, &size, sizeof(size), 0); // recieve the size of the directory
if(n < 0) syserr("can't receive from server");
size = ntohl(size);
int currentSize = 0;
printf("Files at the server: %s\n", argv[1]);
while(currentSize < size){
memset(&buffer[0], 0, sizeof(buffer));
n = recv(sockfd, buffer, 255, 0); // recieve directory from server
if(n < 0) syserr("can't recieve server");
currentSize = currentSize + n;
printf("%s", buffer);
}
}
else if(strcmp(buffer, "ls-local") == 0){ //display files from local directory
printf("Files at the client: \n");
readDirectory();
}
else if(strncmp(buffer, "get ", 4) == 0){ //downlaod file from server
if(strlen(buffer) < 5){ // no file was entered
printf("%s\n", "ERROR...missing filename: get <filename>");
}
else{
uint32_t fileSize;
uint32_t commandSize = strlen(buffer);
//convert to network form
commandSize = htonl(commandSize);
n = send(sockfd, &commandSize, sizeof(commandSize), 0); // send size of command to server
if(n < 0) syserr("can't send to server");
n = send(sockfd, buffer, strlen(buffer), 0); // send command to server
if(n < 0) syserr("can't send to server");
n = recv(sockfd, &fileSize, sizeof(fileSize), 0); // get size of file
if(n < 0) syserr("can't receive from server");
fileSize = ntohl(fileSize);
if(fileSize == -1){
printf("%s\n", "File does not exist");
}
else{ // file exists
int totalBytes = 0;
int bytesWritten = 0;
// get file name
char *fileName = strtok(buffer, " ");
fileName = strtok(NULL, " ");
memcpy(temp, fileName, strlen(fileName)); //copy filename into temp
temp[strlen(fileName)] = '\0';
//create new file with given name
FILE *fpNew = fopen(fileName, "w");
if(fpNew){
while(totalBytes < fileSize){
//receieve the bytes
n = recv(sockfd, buffer, sizeof(buffer), 0);
if(n < 0) syserr("can't receive from server");
//write the bytes
int b = fwrite(buffer, 1, n, fpNew);
if (b < 0)
syserr("error writing file");
if(n == 0){ // error reading on server side
break;
}
totalBytes = n + totalBytes;
bytesWritten = b + bytesWritten;
}
fclose(fpNew);
if(bytesWritten == fileSize) // all bytes read/written to file successfully
printf("Retrieval of file %s: successful.\n", temp);
else
printf("Retrieval of file %s: unsuccessful.\n", temp);
}
else{
syserr("couldnt open file for writing.");
}
}
}
}
else if(strncmp(buffer, "put ", 4) == 0){ // upload file to server
if(strlen(buffer) < 5){
printf("%s\n", "ERROR...missing filename: get <filename>");
}
else{
uint32_t commandSize = strlen(buffer);
uint32_t status;
memcpy(temp, buffer, strlen(buffer)); //copy buffer into temp
temp[strlen(buffer)] = '\0';
// get name of file
char *fileName = strtok(temp, " ");
fileName = strtok(NULL, " ");
int bytes;
FILE *fp = fopen(fileName, "r"); // open the file
if(fp){ // file exists and opened
int totalBytes = 0;
//convert to network form
commandSize = htonl(commandSize);
n = send(sockfd, &commandSize, sizeof(commandSize), 0); // send size of command to server
if(n < 0) syserr("can't send to server");
n = send(sockfd, buffer, strlen(buffer), 0); // send command to server
if(n < 0) syserr("can't send to server");
// get file size
fseek(fp, 0L, SEEK_END);
int fileSize = ftell(fp);
// send the file size
uint32_t size = htonl(fileSize);
n = send(sockfd, &size, sizeof(size), 0);
if(n < 0) syserr("can't send to server");
//go back to beginning of file
fseek(fp, 0, SEEK_SET);
while(totalBytes < fileSize){ // while there are more bytes...
bytes = fread(buffer, 1, sizeof(buffer), fp); // read bytes fromt he file
if(bytes < 0){
syserr("Error reading the file.");
}
totalBytes = totalBytes + bytes;
//send the bytes
n = send(sockfd, buffer, bytes, 0);
if(n < 0) syserr("can't send to server");
if(bytes == 0){ //error reading
break;
}
}
fclose(fp);
//recieve the final status
n = recv(sockfd, &status, sizeof(status), 0);
if(n < 0) syserr("can't receive from server");
status = ntohl(status);
if(totalBytes == fileSize && status == 1){ // successful on both ends
printf("Upload of file %s: successful.\n", fileName);
}
else{
printf("Upload of file %s: unsuccessful.\n", fileName);
}
}
else{
printf("%s\n", "File does not exist");
}
}
}else if(strcmp(buffer, "exit") == 0){
uint32_t commandSize = strlen(buffer);
//convert to network form
commandSize = htonl(commandSize);
n = send(sockfd, &commandSize, sizeof(commandSize), 0); // send size of command to server
if(n < 0) syserr("can't send to server");
n = send(sockfd, buffer, strlen(buffer), 0); // send command to server
if(n < 0) syserr("can't send to server");
}
else{
if(strcmp(buffer, "exit") != 0)
printf("Error...invalid command.\nValid commands: ls-remote, ls-local, get <filename>, put <filename>, exit\n");
}
}while (strcmp(buffer, "exit") != 0);
printf("Connection to server %s:%s terminated, BYE now!\n", argv[1], argv[2]);
close(sockfd);
return 0;
}
void readDirectory(){
DIR *d = opendir(".");
struct dirent *dir;
if (d)
{
while((dir = readdir(d))!= NULL)
{
printf("%s\n", dir->d_name);
}
closedir(d);
}
else{
syserr("Error...could not get files from directory.");
}
}
my server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <dirent.h>
void syserr(char *msg){
perror(msg); exit(-1);
}
void errorHandling(char *msg, int newsockfd){
close(newsockfd);
perror(msg); exit(-1);
}
uint32_t directorySize();
void handle_client(int newsockfd);
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
struct sockaddr_in serv_addr, clt_addr;
socklen_t addrlen;
if(argc < 1) {
fprintf(stderr,"Usage: %s <port>\n", argv[0]);
return 1;
}
if(argc == 1){
argv[1] = "5555";
}
portno = atoi(argv[1]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) syserr("can't open socket");
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0)
syserr("can't bind");
printf("bind socket to port %d...\n", portno);
listen(sockfd, 5);
for(;;){
printf("wait on port %d...\n", portno);
addrlen = sizeof(clt_addr);
newsockfd = accept(sockfd, (struct sockaddr*)&clt_addr, &addrlen);
if(newsockfd < 0) syserr("can't accept");
pid_t pid = fork();
if(pid < 0){
syserr("Error can't fork");
}
else if(pid == 0){ // child process
close(sockfd);
handle_client(newsockfd);
close(newsockfd);
break;
}
else{ // parent
close(newsockfd);
continue;
}
}
return 0;
}
uint32_t directorySize(int newsockfd){
DIR *d = opendir(".");
struct dirent *dir;
uint32_t count = 0;
if (d)
{
while((dir = readdir(d))!= NULL)
{
//count++;
count = strlen(dir->d_name) + count + 1;
}
closedir(d);
}
else{
errorHandling("Error...could not get files from directory.", newsockfd);
}
return count;
}
void handle_client(int newsockfd){
// receieve command size from client
uint32_t commandSize;
int n;
char buffer[256];
while(1){
n = recv(newsockfd, &commandSize, sizeof(commandSize), 0); // receive size of command
if(n < 0) errorHandling("can't receive from client", newsockfd);
commandSize = ntohl(commandSize);
//recieve command
n = recv(newsockfd, buffer, commandSize, 0);
if(n < 0) errorHandling("can't receive from client", newsockfd);
else buffer[n] = '\0';
if(strcmp(buffer, "ls-remote") == 0){ //display files from server directory
// get the size of the directory
uint32_t size = htonl(directorySize(newsockfd));
n = send(newsockfd, &size, sizeof(size), 0); // send size of directory
if(n < 0) errorHandling("can't send to client", newsockfd);
DIR *d = opendir(".");
struct dirent *dir;
if(d){
while((dir = readdir(d))!= NULL){
memset(&buffer[0], 0, sizeof(buffer));
strcpy(buffer, dir->d_name);
buffer[strlen(buffer)] = '\n';
// send file/folder names
n = send(newsockfd, buffer, strlen(buffer), 0);
if(n < 0)
errorHandling("can't receive from client", newsockfd);
}
closedir(d);
}
else{
errorHandling("Error...could not get files from directory.", newsockfd);
}
}
else if (strncmp(buffer, "get", 3) == 0){ // if command is get
char *fileName = strtok(buffer, " "); // "get"
fileName = strtok(NULL, " "); // the name of the file
FILE *fp = fopen(fileName, "r");
if(fp){ // if file exists
int totalBytes = 0;
int bytes;
// get the size of the file
fseek(fp, 0L, SEEK_END);
int fileSize = ftell(fp);
// send the file size
uint32_t size = htonl(fileSize);
n = send(newsockfd, &size, sizeof(size), 0);
if(n < 0) errorHandling("can't send to client", newsockfd);
//go back to beginning of file
fseek(fp, 0, SEEK_SET);
while(totalBytes < fileSize){ // while there are more bytes to read...
// read the bytes into the buffer
bytes = fread(buffer, 1, sizeof(buffer), fp);
if(bytes < 0){
errorHandling("Eorror reading bytes on server side", newsockfd);
}
//send the bytes
n = send(newsockfd, buffer, bytes, 0);
if(n < 0) errorHandling("can't send to client", newsockfd);
if(bytes == 0) // error reading file; bytes should have been > 0
break;
totalBytes = totalBytes + bytes;
}
fclose(fp);
}
else{
// tell client file doesnt exist by sending -1
uint32_t dne = htonl(-1);
n = send(newsockfd, &dne, sizeof(dne), 0);
if(n < 0) errorHandling("can't send to client", newsockfd);
}
}
else if (strncmp(buffer, "put", 3) == 0){ // upload a file
int totalBytes = 0;
int bytesWritten = 0;
int b = 0;
uint32_t fileSize, status;
n = recv(newsockfd, &fileSize, sizeof(fileSize), 0);// receive the size of file
if(n < 0) errorHandling("can't receive from client", newsockfd);
fileSize = ntohl(fileSize);
// get file name
char *fileName = strtok(buffer, " ");
fileName = strtok(NULL, " ");
//create new file with given name
FILE *fpNew = fopen(fileName, "w");
if(fpNew){
while(totalBytes < fileSize){
n = recv(newsockfd, buffer, sizeof(buffer), 0);
if(n < 0) errorHandling("can't receive from client", newsockfd);
if(n == 0){ //bad file transfer on client side
break;
}
//write the bytes
b = fwrite(buffer, 1, n, fpNew);
if(b < n){ // error writing to file
break;
}
totalBytes = totalBytes + n; // bytes recived
bytesWritten = bytesWritten + b; //bytes written
}
fclose(fpNew);
if(bytesWritten != fileSize){ // not all bytes written
status = htonl(-1);
}
else{
status = htonl(1);
}
// send the status
n = send(newsockfd, &status, sizeof(status), 0);
if(n < 0) errorHandling("can't send client", newsockfd);
}
else{
errorHandling("could not open file for writing.", newsockfd);
}
}
else{ // command is exit
printf("%s\n", "closing connection");
close(newsockfd); // close the connection
break;
}
}
}
n = recv(sockfd, &size, sizeof(size), 0); // recieve the size of the directory
if(n < 0) syserr("can't receive from server");
That's not sufficient. If n == 0 the peer has closed the connection: you must do likewise and exit the read loop, or indeed possibly the entire process in your case.

cant send file through socket C

it works only when i do it with my own Computer , but when i use another Computer the file recieved is a mess and the size is always another.
Server:
while (1) {
ZeroMemory(r_buf, MAX_BUFF_RECV - 1);
bytesReceived = recv(sock, r_buf, FILE_DOWNLOAD_SIZE, 0);
if (bytesReceived < 0) {
// ERROR
puts("[!] recv failed");
return;
}
else if (bytesReceived < FILE_DOWNLOAD_SIZE) {
// LAST CHUNCK
if (WriteFile(out, r_buf, bytesReceived, &n, NULL) == FALSE) {
printf("WriteFile() error %d\n", GetLastError());
}
break;
}
else {
if (WriteFile(out, r_buf, bytesReceived, &n, NULL) == FALSE) {
printf("WriteFile() error %d\n", GetLastError());
}
}
}
Client:
while (1)
{
ZeroMemory(buff, FILE_DOWNLOAD_SIZE);
nread = fread(buff, 1, FILE_DOWNLOAD_SIZE, f);
if (nread != FILE_DOWNLOAD_SIZE) {
send(s, buff, nread, 0);
break;
}
else {
send(s, buff, nread, 0);
}
}
im for hours on it , pls tell me whats wrong
In connection-oriented transports, like TCP, send() and recv() are not 1-to-1. There is no guarantee that what you send() will be transmitted in a single data packet, or that recv() will receive everything that you send() in a single go.
There is no guarantee that send() will even accept everything that you give it. It will copy whatever it can into the socket's outbound buffer and return the actual number of bytes copied. So it can accept fewer bytes than requested.
Likewise, recv() will copy whatever data is currently available in the socket's inbound buffer, at least 1 byte but not more than the specified number of bytes, into your specified buffer and will return the actual number of bytes copied. So it can receive fewer bytes than requested.
You also need to know how much file data is actually being transmitted so you know when to stop reading the data. Since recv() can return fewer bytes than requested, you cannot rely on buffer sizes alone to indicate EOF.
You are not taking any of this into account in your code.
Try something more like this instead:
Server:
bool readRaw(SOCKET sock, void *buf, int bufSize)
{
char *pbuf = (char*) buf;
while (bufSize > 0)
{
int bytesReceived = recv(sock, pbuf, bufSize, 0);
if (bytesReceived < 0)
{
printf("[!] recv() error %d\n", WSAGetLastError());
return false;
}
else if (bytesReceived == 0)
{
puts("[!] client disconnected");
return false;
}
else
{
pBuf += bytesReceived;
bufSize -= bytesReceived;
}
}
return true;
}
...
unsigned __int64 fileSize = 0;
if (readRaw(sock, &fileSize, sizeof(fileSize)))
{
while (fileSize > 0)
{
int bufSize = min(fileSize, MAX_BUFF_RECV);
if (!readRaw(sock, r_buf, bufSize))
break;
if (!WriteFile(out, r_buf, bufSize, &n, NULL))
{
printf("[!] WriteFile() error %d\n", GetLastError());
break;
}
fileSize -= bufSize;
}
}
Client:
bool sendRaw(SOCKET sock, void *buf, int bufSize)
{
char *pbuf = (char*) buf;
while (bufSize > 0)
{
int bytesSent = send(sock, pbuf, bufSize, 0);
if (bytesSent < 0)
{
printf("[!] send() error %d\n", WSAGetLastError());
return false;
}
else
{
pBuf += bytesSent;
bufSize -= bytesSent;
}
}
return true;
}
...
fseek(f, 0, SEEK_END);
long int pos = ftell(f);
fseek(f, 0, SEEK_SET);
if (pos == -1)
printf("[!] ftell() error\n");
else
{
unsigned __int64 fileSize = pos;
if (sendRaw(s, &fileSize, sizeof(fileSize)))
{
while (fileSize > 0)
{
int bufSize = min(FILE_DOWNLOAD_SIZE, fileSize);
nread = fread(buff, 1, bufSize, f);
if (nread == 0)
{
printf("[!] fread() error\n");
break;
}
if (!sendRaw(s, buff, nread))
break;
uifileSize -= nread;
}
}
}

How do I delay my message by one second? UDP client

I'm making a program to send and receive messages over a network, I currently have it set up to repeat the message 50 times, but I'd like it to delay each message by one second. Is there a way I can do this using select? If not, how else can I do it?
Thanks.
Here's the code for my client
void
client (char * servername) {
ssize_t bytes;
int skt;
char buff[BUF_SIZE];
int i;
do{
skt = createsocket ( servername, PORT );
bytes = (ssize_t) sprintf (buff, "Hello %s, sequence number:", servername);
if (write (skt, buff, bytes) < bytes) {
fprintf (stderr, "WARNING: write didn't accept complete message\n");
}
memset (buff, 0, BUF_SIZE);
bytes = read (skt, buff, BUF_SIZE);
if (bytes < 0) {
perror ("read()");
exit (1);
}
printf ("Server echoed the following: %s\n", buff);
i++;
}while(i < 50);
}
P.s. I'm also going to try to add a sequence number in there using a long type, how would I go about this?
This should be reasonably close to what you want. (Did not test.)
void client (char * servername)
{
ssize_t bytes;
int skt;
char buff[BUF_SIZE];
int i = 0;
long seqNum = 0;
skt = createsocket ( servername, PORT );
do
{
memset (buff, 0, BUF_SIZE);
struct timeval t = {1, 0};
select(0, NULL, NULL, NULL, &t);
bytes = (ssize_t) sprintf (buff, "Hello %s, sequence number: %ld", servername, seqNum++);
if (write (skt, buff, bytes) < bytes)
{
fprintf (stderr, "WARNING: write didn't accept complete message\n");
}
memset (buff, 0, BUF_SIZE);
bytes = read (skt, buff, BUF_SIZE);
if (bytes < 0)
{
perror ("read()");
exit (1);
}
printf ("Server echoed the following: %s\n", buff);
i++;
}
while (i < 50);
}

Resources