服务器无法从客户端正确读取数据|| C语言

时间:2018-12-01 19:07:57

标签: c sockets client-server

我正在学习C语言的套接字编程,我们必须编写一个TCP客户端/服务器,其中客户端将文件逐行发送到服务器,以便它可以执行以下两项操作之一(min,avg)它将输出发送回客户端。

输入文件遵循以下格式:

AVG 1 2 3 4 5 6
MIN 1 2 3 4 5 -8
MIN 1 2 3 0 5 6

问题是服务器仅读取一行并进行计算,并且出于某种原因,客户端的输出后面还会跟有零!

服务器代码:

#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> 
#define  MAXLINE    4096

double average(int num[],int iterations); //to find the average value
int minimun(int num[],int iterations); //to find the minimum value
double get_op(char b[],int op); //to distinguish between the operations
int startswith(const char *pre, const char *str); //to find if the operatioon is valid only min or avg

int main(int argc, char *argv[]){
    if(argc != 2){ //recieves portnumber
        printf("Missing port number please try again.\n");
        return 1;
    }
    int listenfd = 0, connfd = 0 , line = 0;
    char SENDBUFFER[2048] = "\0";
    char recvBuff[2048] = "\0";
    struct sockaddr_in serv_addr; 
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, '0', sizeof(serv_addr)); 
    memset(recvBuff, '0', sizeof(recvBuff)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(atoi(argv[1]));
    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 
    listen(listenfd, 4); //listens to 4 clients max
    while(1)
    {
        socklen_t szaddr = sizeof(serv_addr);
        connfd=accept(listenfd,(struct sockaddr*)&serv_addr,&szaddr);
        int pid; 
        if( (pid = fork()) == 0 ) { // Child
            close(listenfd);//close listening sock
            printf("Connected...");     
            while(1){
                read(connfd,recvBuff,sizeof(recvBuff)-1);
                int op;
                line++;
                double ans;
                if(startswith("AVG ",recvBuff)){
                    op = 1;
                    ans = get_op(recvBuff,1);
                    sprintf(SENDBUFFER," %f",ans);
                    strcat(recvBuff," = ");
                    strcat(recvBuff,SENDBUFFER);
                    write(connfd, recvBuff, strlen(recvBuff));
                } 
                if(startswith("MIN ",recvBuff)){
                    op = 2;
                    ans = get_op(recvBuff,2);
                    sprintf(SENDBUFFER," %f",ans);
                    strcat(recvBuff," = ");
                    strcat(recvBuff,SENDBUFFER);
                    write(connfd, recvBuff, strlen(recvBuff));
                } 
                else{
                    memset(SENDBUFFER, '0', sizeof(SENDBUFFER));
                    strcat(SENDBUFFER,"Unsupported Operation on Line #");
                    char *str = "";
                    sprintf(str, "%d", line);
                    strcat(SENDBUFFER,str);
                    write(connfd, SENDBUFFER, strlen(SENDBUFFER));
                    }
                }
         close(connfd);
         sleep(1);// child terminates
        }else {// Parent
            close(connfd); // close connected socket
        }
    }
    return 0;
}
int minimun(int num[],int iterations){ 
    int c;
    int min = num[0];
    for (c = 0;c<iterations; c++){
            if (num[c] <= min){
            min = num[c];
            }
        }
    return min;
}
int startswith(const char *pre, const char *str){
    char cp;
    char cs;
    if (!*pre)
        return 1;
    while ((cp = *pre++) && (cs = *str++)){
        if (cp != cs)
            return 0;
    }
    if (!cs)
        return 0;
    return 1;
}
double average(int num[],int iterations){
    int sum = 0,c = 0;
    double avg = 0;
    int i;
    for(i = 0;i<iterations;i++){
        sum=sum+num[i];
    }
    avg=(double)sum/iterations;
    return avg;
}
double get_op(char b[],int op){
    int arr[2048], idx=0, d, l=0;
    char *p; int counter = 0;
    for (p = b; *p != 0; p+=l) {
            l = 1;
            if (isdigit(*p)){
                sscanf(p, "%d%n", &d, &l);
                arr[idx++] = d;
            }   
    }   
    if(op==1)//avg
        return average(arr,idx);
    else     //min
        return (double)(minimun(arr,idx));
}

这是客户端代码:

/* Client Code - Client.c */
#include <unistd.h> 
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h> 
#include <stdlib.h>
#define  MAXLINE    4096
#define filename "path to file"

int main(int argc,char *argv[])
{
    char SENDBUFFER [MAXLINE] = "\0";
    char recvBuff   [MAXLINE] = "\0";
    struct sockaddr_in serv_addr;
    //int len; 
    int sockfd ;
    if(argc<5){
    printf("usage:serv_IP_addr, serv_port,num_of_microsec,nam_of_fil to read the input from\n");
    exit(0);}
    memset(SENDBUFFER, '0', sizeof(SENDBUFFER));
    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(atoi(argv[2])); // port
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    /* Attempt a connection */
    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0){
        printf("\n Error : Connect Failed \n");
        return 1;
    }
    FILE *file; //file to read from
            file = fopen("file path", "r"); //path to file
            if (file == NULL){
                printf("File not found!\n");
                return 1;
            }
            printf("Found file %s\n", filename);
            printf("Sending the file now\n");
            //write function
            while(fgets(SENDBUFFER, MAXLINE,file)!=NULL){
                write(sockfd, SENDBUFFER, sizeof(SENDBUFFER)-1);
            }
            //read function
            memset(recvBuff,'0',sizeof(recvBuff));
            int n ;
            while((n=read(sockfd,recvBuff,sizeof(recvBuff)-1))> 0){
                if(fputs(recvBuff,stdout)==EOF){
                    printf("\n Error : nothing recieved\n");
                }
            } 
            printf("\nDone Sending the File!\n");
            printf("Now Closing Connection.\n");
            fclose(file);
            close(sockfd);
    return 0;
}

P.S:我添加了fork(),因为我试图使服务器最多容纳4个客户端,而其他服务器仍在等待,但仍未完成。

0 个答案:

没有答案