0

Basically my program is suppose to be able to have multiple connections to a server at the same time. Which I have running, except when they have to send large amounts of text via a socket, then it is unpredictable. Sometimes it works, sometimes not. The plaintext4 file is 69,333 bytes long, when I try to send it 5 times at the same time over the network via a socket to a server and back, it doesn't work always; sometimes it works, sometimes parts of it is missing, etc. When I used basically the same thing using write and read it worked, but when I tried to the same with large amounts of text, it didn't work almost at all, hence why I switched to send and recv. Now I can't figure out how to make it so when someone is sending sometime, no one else will send at the same time... because I think that is the problem I am having. Any help would great.

The status of my program right now:

- Works when sending small amounts of text.

- Doesn't work when sending large amounts of text.

- The size of the file that it creates when it doesn't work can vary, sometimes is above 60K bytes sometimes as little as 20K bytes. Meaning that probably one of the other processes wrote to the socket or read from it before the correct process got to receive it. (I think).

server code

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

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
    const int BUFF_SIZE = 70000;
    int sockfd, newsockfd, portno, newsockfdc;
    socklen_t clilen;
    char buffer[BUFF_SIZE];
    pid_t pid;
    int status;
    char temp[BUFF_SIZE];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    int i;
    if (argc < 2) {
     fprintf(stderr,"ERROR, no port provided\n");
     exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 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(sockfd, (struct sockaddr *) &serv_addr,
          sizeof(serv_addr)) < 0) 
          error("ERROR on binding");
    listen(sockfd,5);
    while(1){
        waitpid(-1, &status, WNOHANG);
        memset(buffer, '\0', sizeof(buffer));
        clilen = sizeof(cli_addr);
        newsockfd = accept(sockfd, 
             (struct sockaddr *) &cli_addr, 
             &clilen);
        if (newsockfd < 0) 
          error("ERROR on accept");
        if((pid=fork())==0)     
        {
            close(sockfd);          
            int d;
            for(i=0; i<1; i++)
            {
                bzero(buffer,BUFF_SIZE);
                //sleep(1);
                d=BUFF_SIZE-1;      
                //n = read(newsockfd,buffer,d);             
                n = recv(newsockfd, buffer, sizeof(buffer), 0);
                if (n < 0) error("ERROR reading from socket");
                bzero(temp, BUFF_SIZE);
                strcpy(temp, buffer);

                n = send(newsockfd, buffer, strlen(buffer)+1, 0);
                //n = write(newsockfd,temp,sizeof(temp));
                if (n < 0) error("ERROR writing to socket");
            }
            close(newsockfd);
            exit(0);
        }
        else{ 
            waitpid(-1, &status, WNOHANG);
            close(newsockfd);
        }
    }
    close(sockfd);
    return 0; 
}

client code

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

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    const int BUFF_SIZE = 70000;
    char buffer[BUFF_SIZE];
    if (argc < 4) {
        fprintf(stderr,"usage %s hostname port\n", argv[0]);
        exit(0);
    }
    int numt;
    numt = atoi(argv[3]);
    char numc[5];
    bzero(numc, 5);
    sprintf(numc, "%d", numt);
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        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);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    bzero(buffer,BUFF_SIZE);
    FILE *fp;
    size_t bytes_read;  
    if((fp=fopen("./plaintext4", "r+"))==NULL)
    {
        perror("fopen(2) file error");
        exit(EXIT_FAILURE);
    } 
    bytes_read = fread(buffer, sizeof(buffer), 1, fp);
    fclose(fp);
    sleep(1);   
    n=send(sockfd, buffer, strlen(buffer)+1, 0);
    if (n < 0) 
        error("ERROR writing to socket");
    bzero(buffer,BUFF_SIZE);
    n=BUFF_SIZE - 1;

    n = recv(sockfd, buffer, sizeof(buffer), 0);
    if (n < 0) 
        error("ERROR reading from socket");

    char filei[90];
    bzero(filei,90);
    strcpy(filei, "plaintext");
    strcat(filei, numc);
    strcat(filei, "_a");
    if((fp=fopen(filei, "w+"))==NULL)
    {
        perror("fopen(2) file error");
        exit(EXIT_FAILURE);
    } 
    bytes_read = fwrite(buffer, strlen(buffer), 1, fp);
    fclose(fp);
    close(sockfd);
    return 0;
    //sleep(1);
    printf("Sending message 1: plaintext1\n");
    bzero(buffer,BUFF_SIZE);
    if((fp=fopen("./plaintext1", "r+"))==NULL)
    {
        perror("fopen(2) file error");
        exit(EXIT_FAILURE);
    } 
    bytes_read = fread(buffer, sizeof(buffer), 1, fp);
    fclose(fp);
    n = send(sockfd, buffer, strlen(buffer)+1, 0);  
    //n = write(sockfd, buffer, strlen(buffer));
    if (n < 0)
        error ("ERROR writing to socket client side");
    bzero(buffer, BUFF_SIZE);
    n=BUFF_SIZE - 1;
    n = recv(sockfd, buffer, sizeof(buffer), 0);
    //n = read(sockfd, buffer, n);
    if (n < 0) 
        error("ERROR reading from socket client side");
    printf("message: %s\n", buffer);
    strcat(filei, "b");
    if((fp=fopen(filei, "w+"))==NULL)
    {
        perror("fopen(2) file error");
        exit(EXIT_FAILURE);
    } 
    bytes_read = fwrite(buffer, strlen(buffer), 1, fp);
    fclose(fp);
    close(sockfd);
    return 0;
}

1 Answers1

0

You server process can (which process accept() call) can be blocked by waitpid - it is can be cause of your problem. Alternatively you can implement waitpid call via SIGCHLD signal handler and remove waitpid from main().

Best regards!

  • I found that my project requirements isn't as stringent as I thought; I only have one time that sends a large file and it is last, plus it has some time before anything else is sent, so my requirements were higher than what was expected of me. But thanks I am sure this answer helped fix my problem as well! –  Dec 05 '15 at 20:37