Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 套接字发送客户端服务器文件_C_Sockets_Pthreads - Fatal编程技术网

C 套接字发送客户端服务器文件

C 套接字发送客户端服务器文件,c,sockets,pthreads,C,Sockets,Pthreads,我编写了一个应用程序,其中客户端使用使用tcp协议的套接字向服务器发送文件 我的服务器是多线程的(带有Pthread) 只有一个问题,将文件复制到服务器比原始文件小(大约2公里)。为什么? 这是我的客户机代码,它开始键入./client filename filenamecopy #include <netdb.h> #include <netinet/in.h> #include <string.h> #include <stdio.h>    

我编写了一个应用程序,其中客户端使用使用tcp协议的套接字向服务器发送文件

我的服务器是多线程的(带有Pthread)

只有一个问题,将文件复制到服务器比原始文件小(大约2公里)。为什么?

这是我的客户机代码,它开始键入./client filename filenamecopy

#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
 
 
int fileSEND(char *server, int PORT, char *lfile, char *rfile){
 
    int socketDESC;
    struct sockaddr_in serverADDRESS;
    struct hostent *hostINFO;
    FILE * file_to_send;
    int ch;
    char toSEND[1];
    char remoteFILE[4096];
    int count1=1,count2=1, percent;
 
    hostINFO = gethostbyname(server);
    if (hostINFO == NULL) {
        printf("L'adresse ip du serveur n'est pas accesible\n");
        return 1;
    }
 
    socketDESC = socket(AF_INET, SOCK_STREAM, 0);
    if (socketDESC < 0) {
        printf("Erreur création socket\n");
        return 1;
    }
 
    serverADDRESS.sin_family = hostINFO->h_addrtype;
    memcpy((char *) &serverADDRESS.sin_addr.s_addr, hostINFO->h_addr_list[0], hostINFO->h_length);
    serverADDRESS.sin_port = htons(PORT);
 
    if (connect(socketDESC, (struct sockaddr *) &serverADDRESS, sizeof(serverADDRESS)) < 0) {
        printf("Erreur de connection\n");
        return 1;
    }
 
 
    file_to_send = fopen (lfile,"r");
    if(!file_to_send) {
        printf("Erreur de lecture du fichier\n");
        close(socketDESC);
        return 0;
    } else {
    long fileSIZE;
    fseek (file_to_send, 0, SEEK_END); fileSIZE =ftell (file_to_send);
    rewind(file_to_send);
 
    sprintf(remoteFILE,"FBEGIN:%s:%i\r\n", rfile, fileSIZE);
    send(socketDESC, remoteFILE, sizeof(remoteFILE), 0);
 
    percent = fileSIZE / 100;
    while((ch=getc(file_to_send))!=EOF){
        toSEND[0] = ch;
        send(socketDESC, toSEND, 1, 0);
        if( count1 == count2 ) {
            printf("33[0;0H");
            printf( "\33[2J");
            printf("Nom du fichier: %s\n", lfile);
            printf("Taille du fichier: %i Kb\n", fileSIZE / 1024);
            printf("Poucentage : %d%% ( %d Kb)\n",count1 / percent ,count1 / 1024);
            count1+=percent;
        }
        count2++;
 
    }
    }
    fclose(file_to_send);
    close(socketDESC);
return 0;
}
 
int main(int argc, char* argv[])
{
    fileSEND("127.0.0.1", 31338, argv[1], argv[2]);
    return 0;
}
#包括
#包括
#包括
#包括
 
 
int fileSEND(char*服务器、int端口、char*lfile、char*rfile){
 
int socketDESC;
serverADDRESS中的结构sockaddr_;
结构主机*主机信息;
文件*要发送的文件;
int-ch;
char-toSEND[1];
字符远程文件[4096];
int count1=1,count2=1,百分比;
 
hostINFO=gethostbyname(服务器);
if(hostINFO==NULL){
printf(“可接受的服务地址”);
返回1;
    }
 
socketDESC=socket(AF_INET,SOCK_STREAM,0);
如果(socketDESC<0){
printf(“Erreur création socket\n”);
返回1;
    }
 
serverADDRESS.sin_family=hostINFO->h_addrtype;
memcpy((char*)&serverADDRESS.sin\u addr.s\u addr,hostINFO->h\u addr\u list[0],hostINFO->h\u length);
serverADDRESS.sin_port=htons(端口);
 
if(connect(socketDESC,(struct sockaddr*)&serverADDRESS,sizeof(serverADDRESS))<0){
printf(“连接错误”);
返回1;
    }
 
 
文件发送=fopen(lfile,“r”);
如果(!要发送的文件){
printf(“费希尔讲座的错误”);
关闭(socketDESC);
返回0;
}其他{
长文件大小;
fseek(文件发送,0,搜索结束);fileSIZE=ftell(文件发送);
倒带(文件发送);
 
sprintf(远程文件,“FBEGIN:%s:%i\r\n”,rfile,fileSIZE);
发送(socketDESC,remoteFILE,sizeof(remoteFILE),0);
 
百分比=文件大小/100;
while((ch=getc(文件发送))!=EOF){
toSEND[0]=ch;
发送(socketDESC,toSEND,1,0);
如果(count1==count2){
printf(“33[0;0H”);
printf(“\33[2J”);
printf(“文件名:%s\n”,lfile);
printf(“Taille du fichier:%i Kb\n”,文件大小/1024);
printf(“百分比:%d%%(%d Kb)\n”,计数1/百分比,计数1/1024);
count1+=百分比;
        }
count2++;
 
    }
    }
fclose(文件发送到文件发送);
关闭(socketDESC);
返回0;
}
 
int main(int argc,char*argv[])
{
fileSEND(“127.0.0.1”,31338,argv[1],argv[2]);
返回0;
}
以及服务器,它仅通过./server启动

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <pthread.h>
 
#define PORT 31338
 
int parseARGS(char **args, char *line){
    int tmp=0;
    args[tmp] = strtok( line, ":" );
    while ( (args[++tmp] = strtok(NULL, ":" ) ) != NULL );
    return tmp - 1;
}
 
int client(void *ptr){
    int  connectSOCKET;
    connectSOCKET = (int ) ptr;
    char recvBUFF[4096];
    char *filename, *filesize;
    FILE * recvFILE;
    int received = 0;
    char tempstr[4096];
    char *header[4096];
 
    /*int i=0;
    while(i<993199) {
    i++;*/
    while(1){
        if( recv(connectSOCKET, recvBUFF, sizeof(recvBUFF), 0) ){
            if(!strncmp(recvBUFF,"FBEGIN",6)) {
                recvBUFF[strlen(recvBUFF) - 2] = 0;
                parseARGS(header, recvBUFF);
                filename = header[1];
                filesize = header[2];
                printf("Fichier: %s\n", filename);
                printf("Taille: %d Kb\n", atoi(filesize) / 1024);
        }
        recvBUFF[0] = 0;
        recvFILE = fopen ( filename,"w" );
        while(1){
            if( recv(connectSOCKET, recvBUFF, 1, 0) != 0 ) {
                fwrite (recvBUFF , sizeof(recvBUFF[0]) , 1 , recvFILE );
                received++;
                recvBUFF[0] = 0;
                } else {
                printf("Progression: %s [ %d of %s bytes]\n", filename, received , filesize);
                return 0;
                }
            }
            return 0;
        } else {
        printf("Client déconnecté\n");
        }
    return 0;
    }
}
 
 
int main()
{
    int socketINDEX = 0;
    int listenSOCKET, connectSOCKET[4096];
    socklen_t clientADDRESSLENGTH[4096];
    struct sockaddr_in clientADDRESS[4096], serverADDRESS;
    pthread_t threads[4096];
 
    listenSOCKET = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSOCKET < 0) {
        printf("Peut pas crée socket\n");
        close(listenSOCKET);
        return 1;
    }
 
    serverADDRESS.sin_family = AF_INET;
    serverADDRESS.sin_addr.s_addr = htonl(INADDR_ANY);
    serverADDRESS.sin_port = htons(PORT);
 
    if (bind(listenSOCKET, (struct sockaddr *) &serverADDRESS, sizeof(serverADDRESS)) < 0) {
        printf("Peut pas trouver la socket\n");
        close(listenSOCKET);
        return 1;
    }
 
    listen(listenSOCKET, 5);
    clientADDRESSLENGTH[socketINDEX] = sizeof(clientADDRESS[socketINDEX]);
    int i=0;
    /*while(i<993199) {
    i++;*/
    while(1){
        connectSOCKET[socketINDEX] = accept(listenSOCKET, (struct sockaddr *) &clientADDRESS[socketINDEX], &clientADDRESSLENGTH[socketINDEX]);
        if (connectSOCKET[socketINDEX] < 0) {
            printf("Connection refusé\n");
            close(listenSOCKET);
            return 1;
        }
 
        pthread_create( &threads[socketINDEX], NULL, client, connectSOCKET[socketINDEX]);
        if(socketINDEX=4096) {
            socketINDEX = 0;
        } else {
        socketINDEX++;
        }
    }
    close(listenSOCKET);
}
#包括
#包括
#包括
#包括
#包括
#包括
 
#定义端口31338
 
int parseARGS(字符**参数,字符*行){
int-tmp=0;
args[tmp]=strtok(行“:”);
while((args[++tmp]=strtok(NULL,“:”)!=NULL);
返回tmp-1;
}
 
内部客户端(void*ptr){
int连接插座;
connectSOCKET=(int)ptr;
char recvBUFF[4096];
字符*文件名,*文件大小;
文件*recvFILE;
接收到的int=0;
char-tempstr[4096];
字符*头[4096];
 
/*int i=0;
而(i2个问题:

  • 您的客户端发送一个带有FBEGIN:filename:size标头的4K块。服务器尝试在一个4K块中读取该块。
    recv()
    可能返回的缓冲区少于一个完整的缓冲区(只有1个字节)

  • 服务器读取文件后未关闭该文件。这可能导致文件大小不一致(关闭文件时缓冲数据将被刷新)


  • 这本身不是一个bug,而是一个性能问题:一次读取/写入/发送/接收一个字节是S-L-O-W。您应该在更大的块中完成所有操作(即使只有1K也会大大提高性能)。请记住“
    recv()
    可能会部分完成”上面提到的问题。

    您能再解释一下这个问题吗?好的,谢谢您的回答。1)我必须将4096改为1024?2)我没有倒立,我想添加的是fclose(recvFILE);关闭后(listenSOCKET)?