2

I have socket code and client code below. So far all that it does is establish connection with the server, but I want it to also send a file from the client to the server; even if the file has no data in it. What do I have to do to augment this code to send files? Any suggestions in code form?

Client:

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h> 

int main(int argc, char *argv[])
{
    int sockfd = 0, n = 0;
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    memset(recvBuff, '0',sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
    {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
       printf("\n Error : Connect Failed \n");
       return 1;
    } 

    while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
    {
        recvBuff[n] = 0;
        if(fputs(recvBuff, stdout) == EOF)
        {
            printf("\n Error : Fputs error\n");
        }
    } 

    if(n < 0)
    {
        printf("\n Read error \n");
    } 

    return 0;
} 

Server:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h> 

int main(int argc, char *argv[])
{
    int listenfd = 0, connfd = 0;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    time_t ticks; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, '0', sizeof(serv_addr));
    memset(sendBuff, '0', sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

    listen(listenfd, 10); 

    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

        ticks = time(NULL);
        snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
        write(connfd, sendBuff, strlen(sendBuff)); 

        close(connfd);
        sleep(1);
     }
}
user247702
  • 23,641
  • 15
  • 110
  • 157
B.D.
  • 31
  • 2
  • 6

1 Answers1

-1

I havn't tried compiling this, and this code is certainly not polished but something similar to below will do the trick :)

Modify the client end to look like this:

if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
  printf("\n Error : Connect Failed \n");
  return 1;
} 

FILE *inputFile = fopen("inputFile.txt", "rb");

if(inputFile == NULL)
{
  fprintf(stderr, "oh no!");
  return 1;
}

char sendBuffer[10];

// TODO: Check for errors here
int bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile);

while(!feof(inputFile))
{
  //TODO: check for errors here
  send(sockfd, sendBuffer, bytesRead, 0);
  bytesRead = fread(sendBuffer, sizeof(sendBuffer), 1, inputFile);
} 
close(sockfd);

Modify the server end to look like this:

listen(listenfd, 10); 

FILE *outputFile = fopen("output.txt", "wb");

if(outputFile == null)
{
  fprintf(stderr, "Something went south!");
  return 1;
}

while(1)
{
    connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 

    char recvBuff[10];

    ticks = time(NULL);
    int bytesReceived = recv(confd, recvBuff, 10, 0);
    while(bytesReceived != 0)
    {

      // you should add error checking here
      fwrite(recvBuff, bytesReceived, 1, outputFile);

      bytesReceived = recv(confd, recvBuff, 10, 0);
    }

    close(connfd);
}
Nick Weedon
  • 441
  • 5
  • 10
  • If you wanted to make this really nice, as well as fixing my sloppy code you could make this into a multi threaded version and have the server create a new thread for each client request it receives. If you havn't learnt about threads yet then thats OK, this will work just fine but only for one client at a time. – Nick Weedon Mar 13 '14 at 06:16
  • A good way to learn this type of stuff is to find a good book on it. I highly recommend "Unix for programmers and users" by Graham Glass (http://www.amazon.com/UNIX-Programmers-Users-3rd-Edition/dp/0130465534) – Nick Weedon Mar 13 '14 at 06:23
  • Thanks @NickWeedon . It only needs to handle one file at a time so multiple threads aren't really necessary. I also forgot to mention that it should be able to handle files with no data in them. Will this account for that? Or should it be modified in the send and recieve? – B.D. Mar 13 '14 at 07:26
  • It should do now (i just edited it because i forgot the close on the client side). Once the client closes the connection, this causes the server 'recv' function to return 0 (assigned to bytes received). This is an importent point as this is what triggers the server to stop reading from the socket. – Nick Weedon Mar 13 '14 at 07:34
  • OKay great and one more question. I want to direct the searching for the input file using a file path instead of having it all i n the same folder. I should be able to put the path instead of "inputfile.txt" right? – B.D. Mar 13 '14 at 15:45
  • Yep, that's right, just change the string "inputfile.txt". If you are running windows then don't forget to escape the backslashes ('\'). Example: "c:\temp\myfile.txt" becomes "c:\\temp\\myfile.txt". Enjoy :D – Nick Weedon Mar 13 '14 at 21:36
  • You should loop while bytesReceived > 0, and add the error checking *after* the loop. – user207421 Sep 27 '14 at 10:32
  • 1
    There are in fact so many things wrong with the code I posted its not funny :). It was intended to give the idea, certainly not production grade quality. – Nick Weedon Sep 27 '14 at 12:34