无法传输二进制文件

时间:2013-11-01 21:00:41

标签: c sockets network-programming binaryfiles

我正在尝试构建服务器客户端代码。客户端可以从服务器下载任何文件,但我有二进制文件的问题

这是我的客户代码:

#include <stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<fcntl.h>
#define Max_len 1025
//-------------------------- to replay for pecific secret simpol 0x55
char secret(char * str)
{
    char  sub=0x55;
    if(sub==str[0])
        {
            sub=0xAA;
            return sub;
        }
    else
        {
            printf("server does not give the right secret code\n");
            exit(0);
        }
}
//-------------------------warraper function for perror
void error(char * str)
{
    perror(str);
    exit(0);
}
int main ( int nof_arg, char **argv)
{
    //------------------------define data types
    int sockfd,number,portno,val=0,fil_fd;  //to store the file descreptore of socket
    char rec_lin [Max_len],f_name[20]="\0",car;  // act as buffer
    struct sockaddr_in servaddr;
    char * read_one;
    FILE * file_ptr;  //------------------------ welcome message identife the writer
    printf("\n\t Welcom the client \n\t Name: Eftikhar Emad \n\t ID: 20100175003\n\tsection #1: 9:15-10:15\n\n");
    //------------------------ prepair the client to start connection
    if (nof_arg < 3)            //check the number of entered arregument
        error("you need the IP and port number to connect please check them again\n");

    portno=atoi(argv[2]);           // convert the port from string to int
    if((portno<=22000) || (portno>=23000))  //check to see if the port numberif valiled
        error("your port number is out of range please try agin start with 22XXX\n");

    if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)   //socket creation
        error("Socket creation error");

    bzero(&servaddr,sizeof(servaddr));      //static define for the server
    servaddr.sin_family=AF_INET;
    servaddr.sin_port = htons(portno);

    if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<=0)//it can be used to check
        error("inet_pton error ");

    if((connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))<0)//connection
        error("connect error");

    //------------------------------------start define the server valited
    bzero(rec_lin,sizeof(rec_lin));
    read(sockfd,rec_lin ,sizeof(rec_lin));
    printf("received the byte 0x55 from the server\n"); //will readonly one char
    car=secret(rec_lin);
    printf("Sending ack 0xAA to the server\n");
    bzero(rec_lin,sizeof(rec_lin));
    snprintf(rec_lin,sizeof(rec_lin),"%c",car);
    write(sockfd,rec_lin,1);            //send 0xAA if 0x55


    //-------------------------------------print the list from server
    read(sockfd,rec_lin,sizeof(rec_lin));
    while(rec_lin[0]!= '\0')
        {
            read(sockfd,rec_lin,sizeof(rec_lin));
            printf("%s\n",rec_lin);
        }


    //-------------------------after know the server start to ask and send file name
    printf("enter file name to download : ");
    gets(f_name);                   //rad file name from user
    snprintf(rec_lin,sizeof(rec_lin),"%s",f_name);
    write(sockfd,rec_lin,sizeof(rec_lin));       //send the file name to server
    bzero(rec_lin,sizeof(rec_lin));
    //--------------------------------------check server reply 0/1 for finding or not
    read(sockfd,rec_lin,/*sizeof(rec_lin)*/1);
    int p;
    if(rec_lin[0]==0x31)    //if file found inform the user,start,ending msg
        {           //no creation to file unless it found on server
            printf("Received 1 from server %s exists\nStart downloading the file\n",f_name);
            fil_fd=open(f_name,O_RDWR| O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
            while((val=read(sockfd,rec_lin,sizeof(rec_lin)-1))>0)
                {
                    p=strlen(rec_lin);
                    //  rec_lin[val]='\0';
                    write(fil_fd,rec_lin,/*sizeof(rec_lin)*/p+1);
                    bzero(rec_lin,1049);
                }
            printf("Done Downloadng the file.......exit\n\n");
            close(fil_fd);
        }
    else            //if file not found terminate the connection
        {
            printf("file not found get ... connection will closed\n\n");
        }
    // -----------------------------terminate connection if it Done in the right way
    close(sockfd);
    return 0;

}

这是我的服务器代码:

#include<stdio.h>
#include<errno.h>
#include<arpa/inet.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<fcntl.h>
#include<netdb.h>
#include<dirent.h>
#define Max_len 1025
void error (char * str)
{
    perror(str);
    exit(0);
}
int main (int argc, char ** arg)
{
    / /------------------------- define data type
        int listenfd,connfd,clilen,portno,fil_fd,n;
    char buff[Max_len], *str,f_name[100],car=0xAA,h_IP[30],h_P[20];
    struct sockaddr_in servaddr,cliaddr;
    DIR * ddir;
    struct dirent * ndir;
    //------------------------- socket intinalizing
    printf("\n\t Welcom the server \n\t Name: Eftikhar Emad \n\t ID: 20100175003\n\t section #1: 9:15-10:15\n");

    if(argc != 2)           //of user forget to insert the port number
        error("missing port number to complet establishment\n");

    portno=atoi(arg[1]);        //convert the port to int and check if it was within the rang
    if((portno<=22000) || (portno>=23000))
        error("your port number not valid .... pleas insert one in reng (22000,22999)\n");

    listenfd=socket(AF_INET,SOCK_STREAM,0);     //creat the listing socket
    bzero((char *)&servaddr ,sizeof(servaddr));
    servaddr.sin_family=AF_INET;        //Ipv4
    servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servaddr.sin_port=htons(portno);

    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));//bind the liten socket to specific port
    listen(listenfd,5);
    //-------------------------- server start to wait to handle requests
    for(;;)
        {
            printf("server wait for connections\n");
            bzero((char *)&cliaddr ,sizeof(cliaddr));   //clear the previus client information
            clilen=sizeof(cliaddr);             //client informaton container
            connfd=accept(listenfd,(struct  sockaddr *)&cliaddr,&clilen);
            int f=fork();       //start of fork()
            if(f==0)
                {

                    close(listenfd);
                    if(connfd<0)
                        error("error in accept this connection\n");
                    //---------------------------------------       //start the secret hand chacking
                    bzero(buff,sizeof(buff));
                    getnameinfo((struct sockaddr *)&cliaddr,sizeof(cliaddr),h_IP,sizeof(h_IP),h_P,sizeof(h_P),0);
                    printf("Sending byte 0x55 to client with IP %s and port of %s\n",h_IP,h_P);
                    //get the IP AND port# of the client
                    snprintf(buff,sizeof(buff),"%c",0x55);
                    write(connfd,buff,sizeof(buff));
                    //---------------------------------------       //read file name
                    car=0xAA;
                    read(connfd,buff,sizeof(buff));
                    printf("received 0XAA from client \n");
                    if(car==buff[0])
                        {
                            //------- send the list to the client
                            snprintf(buff,sizeof(buff),"select file to download it\n");
                            write(connfd,buff,sizeof(buff));
                            ddir=opendir(".");
                            if(ddir==NULL)
                                {printf("error\n");exit(0);}
                            while((ndir=readdir(ddir))!=NULL)
                                {//printf("%s\n",ndir->d_name);
                                    snprintf(buff,sizeof(buff),"%s",ndir->d_name);
                                    printf("%s\n",buff); 
                                    write(connfd,buff,sizeof(buff));
                                }
                            write(connfd,"\0",1);
                            closedir(ddir);


                            read(connfd,buff,sizeof(buff));     //get the name after get 0xAA
                            strncpy(f_name,buff,sizeof(buff)-1);
                        }
                    else
                        { printf("this is not secure client\n");break;}

                    //--------------------------------------   if file found send 1 else 0
                    fil_fd=open(f_name,O_RDONLY);       //file opent to be read only
                    if(fil_fd < 0)
                        {
                            snprintf(buff, sizeof(buff),"%d",0);
                            write(connfd,buff,1);
                            printf("file is not found\n");      //retminate connection only
                            break;
                        }
                    else
                        {
                            snprintf(buff, sizeof(buff),"%d",1);
                            write(connfd,buff,sizeof(buff));
                            printf("file exists.Send %s to client\n",buff);
                            //-----------------------------------reading and sending
                            while((n=read(fil_fd,buff,sizeof(buff)-1))>0)
                                {   buff[n]='\0';
                                    write(connfd,buff,/*sizeof(buff)*/n+1); //sending the file process
                                    bzero(buff,sizeof(buff));
                                }//end of uploading
                            printf("end download thf file");
                            close(fil_fd);
                        }//end of if_else
                    close(connfd);
                    exit(0);
                }//end of child code
            else
                {
                    //wait(NULL);
                    printf("-------------------------------\n");
                    close(connfd);
                }
        }//end of for()
    //--------------------------------------------prepair the server connection
    close(listenfd);
    exit(0);

    return 0;
}//main()

如果我将它与“file.txt”一起使用,这段代码可以正常工作。 我希望在不使用fread()fwritefopen的情况下将其与二进制文件一起使用。 有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

您无法编写忽略read(),recv()等返回值的正确网络软件。这些函数返回-1表示错误,0表示流结束或读取计数。您现在的代码忽略了所有三种可能性,它还假设read()填充缓冲区。没有任何地方可以这么说。

编辑:我应该明确指出,这同样适用于从任何来源阅读,而不仅仅是网络。

答案 1 :(得分:0)

我的问题是......使用open()将创建文件数据,因此当执行二进制文件时会出现“无法执行二进制文件”。

解决方案:使用fopen(file_name,"r+b")可以创建以不同于文本文件

的方式获取二进制文件的文件