使用tcp从服务器向客户端发送文件

Sending file from server to client using tcp

我正在尝试将文件从服务器发送到客户端,代码是 运行,没有任何错误,但是当客户端创建文件时,我没有获得文件中所需的数据该服务器正在发送。

我在 Whosebug 本身上查找了一些解决方案,但无法解决我的问题,因为我是套接字编程的新手,谁能告诉我我要去哪里 wrong.please 帮助我!!

这是代码

server.c

// Server side C/C++ program to demonstrate Socket programming
#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> 

#include <netdb.h>
#include <sys/sendfile.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>

//#define PORT 8080
int main(int argc, char const *argv[])
{
int fq;

 struct sockaddr_in client,server;
    struct hostent *h;

struct stat st;
int len = 0;
int PORT = strtol(argv[1], NULL, 10);


 char *filename = strdup(argv[2]);




    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char *hello = "Hello from server";

if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}


    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // Forcefully attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                                                  &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address, 
                                 sizeof(address))<0)
    {
        fprintf(stderr, "%s", "Bind Failed\n");    
            exit(2);
    }
    else {   printf("BindDone: %s\n ", argv[1]);

}


    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }

else {   printf("ListenDone: %s\n ", argv[1]);

}

    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, 
                       (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
///////////////////////////////////////////
    fq = open(filename, O_RDONLY);
    if( fq < 0 )
    {
        fprintf(stderr, "%s", "File error\n");    
            exit(3);
    }

stat(filename,&st);
    len = st.st_size;

    if(sendfile(server_fd,fq,0,len) < 0)
    {
        perror("send error");
        exit(1);
    }

 //   close(sd);





    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");

    printf("TransferDone: %s\n ", "bytes\n");

 close(fq);
close(server_fd);
 return 0;
}

client.c

// Client side C/C++ program to demonstrate Socket programming

#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>
#define PORT 8080
#define MAX_LEN 512

int main(int argc, char const *argv[])
{
struct sockaddr_in server;
    struct sockaddr_in client;  


int rn ;
    struct sockaddr_in address;
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char *hello = "Hello from client";
    char buffer[MAX_LEN] ;

    FILE *fp;
    int i;
    char *filename = strdup(argv[2]);




if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}



    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }

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

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

    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) 
    {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        fprintf(stderr, "%s", "Server connection error\n");    
            exit(2);
    }

///////////////////////
fp=fopen( filename, "ab");
    if(fp == NULL)
    {
        fprintf(stderr, "%s", "file not readable\n");    
            exit(3);
    }

////////////////////////

while(1)
    {
        rn=recv(sock,buffer,MAX_LEN,0);

        if(rn < 0)
        {
            printf( "Can 't receive file!\n ");
            exit(1);
        }

        buffer[rn]= '[=11=] ';

        if(rn != 0)
        {
            fwrite(buffer,1,512,fp);
            bzero(buffer,sizeof(buffer));
        }
        else
        {
            printf("receive over.\n");
            break;
        }
    }



/////////////////////////



    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    valread = read( sock , buffer, 1024);
    printf("%s\n",buffer );

fclose(fp);
    return 0;
}

检查这个:

server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define PORT 2024
extern int errno;
int main (){
  struct sockaddr_in server;
  struct sockaddr_in from;  
  int sd;
  sd = socket (AF_INET, SOCK_STREAM, 0);
  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));

  server.sin_family = AF_INET;  
  server.sin_addr.s_addr = htonl (INADDR_ANY);
  server.sin_port = htons (PORT);
  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1){
      perror ("bind(). error\n");
      return errno;
  }
  if (listen (sd, 5) == -1){
      perror ("listen(). error\n");
      return errno;
  }
  while (1){
      int client;
      int length = sizeof (from);
      printf ("connect to port :  %d...\n",PORT);
      fflush (stdout);
      client = accept (sd, (struct sockaddr *) &from, &length);
      if (client < 0)
         continue;
      char file[100];

      read (client, file, 100) <= 0;
      printf("Filename : %s\n\n", file); 
      //
        FILE *fl = fopen(file, "r");
        char text[500]; //your file size
        int len = 0;
        char c;

        while((c = fgetc(fl)) != EOF){
            text[len] = c;
            len++;    
        }
        text[len] = '[=10=]';
        //printf("%d", len);
        //printf("%s", text);
        write(client, &len, 4);
        write(client, text, len);
      close (client);
    }       
}       

client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <string.h>
extern int errno;
int port;
int main (int argc, char *argv[]){
  int sd;   
  struct sockaddr_in server;

  if (argc != 3){
      printf ("%s <server_adress> <port>\n", argv[0]);
      return -1;
  }
  port = atoi (argv[2]);
  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
      perror ("socket() error.\n");
      return errno;
  }
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = inet_addr(argv[1]);
  server.sin_port = htons (port);
  if (connect (sd, (struct sockaddr *) &server,sizeof (struct sockaddr)) == -1){
      perror ("connect(). error\n");
      return errno;
  }
  char file[100]; 
  printf("Give me filename: ");
  fflush(stdout);
  scanf("%s", file);
  if (write (sd, file, 100) <= 0)
    {
      perror ("[client]Eroare la write() spre server.\n");
      return errno;
    }
   int len;
   char text[500];
   read(sd, &len, 4);
   read(sd, text, len);
   //printf("%s\n", text);
   FILE *fl = fopen("newFile.txt", "w");
   fprintf(fl, "%s", text);
   fclose(fl);
   close (sd);
}

这里客户端给服务器一个文件名,它(服务器)打开文件并从中读取所有内容,将数据发送给创建新文件的客户端并将数据写入新创建的文件。

更新。

concurentServer.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#define PORT 2908
extern int errno;
typedef struct thData{
    int idThread; 
    int cl;
}thData;
static void *treat(void *); 
void answer(void *);

int main (){
  struct sockaddr_in server;
  struct sockaddr_in from;  
  int nr;    
  int sd;   
  int pid;
  pthread_t th[100];  
    int i=0;
  if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == -1){
      perror ("[server]socket().\n");
      return errno;
  }
  int on=1;
  setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
  bzero (&server, sizeof (server));
  bzero (&from, sizeof (from));
    server.sin_family = AF_INET;    
    server.sin_addr.s_addr = htonl (INADDR_ANY);
    server.sin_port = htons (PORT);
  if (bind (sd, (struct sockaddr *) &server, sizeof (struct sockaddr)) == -1) {
      perror ("[server]bind().\n");
      return errno;
  }
  if (listen (sd, 2) == -1){
      perror ("[server]listen().\n");
      return errno;
  }
  while (1){
      int client;
      thData * td;      
      int length = sizeof (from);
      printf ("[server]Port :  %d...\n",PORT);
      fflush (stdout);
      if ( (client = accept (sd, (struct sockaddr *) &from, &length)) < 0){
             perror ("[server]accept().\n");
             continue;
        }

       int idThread; 
       int cl; 
    td=(struct thData*)malloc(sizeof(struct thData));   
    td->idThread=i++;
    td->cl=client;
      pthread_create(&th[i], NULL, &treat, td);             
    }
};


static void *treat(void * arg)
{       
        struct thData tdL; 
        tdL= *((struct thData*)arg);    
        printf ("[thread]- %d - Waiting for message...\n", tdL.idThread);
        fflush (stdout);         
        pthread_detach(pthread_self());     
        answer((struct thData*)arg);
        close ((intptr_t)arg);
        return(NULL);   

};


void answer(void *arg){
        char file[100];
          int ap;
        struct thData tdL; 
          tdL= *((struct thData*)arg);
        //
        if (read (tdL.cl, file, 100) <= 0){
                  printf("[Thread number : %d]\n",tdL.idThread);
              }
          FILE *fl = fopen(file, "r");
        char text[500]; //your file size
        int len = 0;
        char c;

        while((c = fgetc(fl)) != EOF){
            text[len] = c;
            len++;    
        }
        text[len] = '[=12=]';
        //printf("%d", len);
        //printf("%s", text);
        write(tdL.cl, &len, 4);
        write(tdL.cl, text, len);
}

因此,当我以前尝试解决它时遇到了问题,但现在我已经成功解决了这里是 客户端代码:

#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 const *argv[])
{

int byte_count=0;
int sockfd = 0;
    int bytesReceived = 0;
    char recvBuff[256];
    memset(recvBuff, '0', sizeof(recvBuff));
    struct sockaddr_in serv_addr;

if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}

char *first_argument = strdup(argv[1]);
//printf("%s\n",first_argument);
char *filename = strdup(argv[2]);

//extract port and ip address from first argument


int c;
//char *first_argument = strdup(argv[1]);

for(int i = 0; first_argument[i] != '[=10=]'; i++) {

if(first_argument[i]==':') c=i;

}


char *ip = (char*) malloc(c+1);
char *tto = (char*) malloc(c+1);
strncpy(ip, first_argument, c);
strncpy(tto, first_argument+c+1, c);


//printf("%s\n",ip);
//printf("%s\n",tto);

int port = atoi(tto);

//printf("%d\n",port);


////////////////////////////////
    /* Create a socket first */
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    }

    /* Initialize sockaddr_in data structure */
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port); // port
    serv_addr.sin_addr.s_addr = inet_addr(ip);

    /* Attempt a connection */
connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
printf("ConnectDone: %s\n", argv[1]);   

//    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0)
  //  {
    //     fprintf(stderr, "%s", "server connect failed\n");    
    //      exit(1);

    //}

    /* Create file where data will be stored */
    FILE *fp;
    fp = fopen(filename, "ab"); 
    if(NULL == fp)
    {
        fprintf(stderr, "%s", "error opening file\n");    
            exit(3);
    }

    /* Receive data in chunks of 256 bytes */
    while((bytesReceived = read(sockfd, recvBuff, 256)) > 0)
    {
   //     printf("Bytes received %d\n",bytesReceived);    
        // recvBuff[n] = 0;
        fwrite(recvBuff, 1,bytesReceived,fp);
        // printf("%s \n", recvBuff);
byte_count +=bytesReceived;
    }

  //  if(bytesReceived < 0)
    //{
      //  printf("\n Read Error \n");
    //}

printf("FileWritten: %d bytes\n", byte_count);   
    return 0;
}

和服务器代码:

#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>

int main(int argc, char const *argv[])
{

    int byte_count = 0 ;
    int listenfd = 0;
    int connfd = 0;
    struct sockaddr_in serv_addr;
    char sendBuff[1025];
    int numrv;

//checking if correct number of arguments are given on the command line
if(argc != 3 ) {  fprintf(stderr, "%s", "wrong command line arguments\n");    
            exit(1);                    

}
//converting arguments to their correct types to use them e.g. port num and filename 
int PORT = strtol(argv[1], NULL, 10);
char *filename = strdup(argv[2]);
//printf("%s",filename);


    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    //printf("Socket retrieve success\n");

    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(PORT);


//bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
//checking if bind fails??



if (bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr))== -1)
    {
        fprintf(stderr, "%s", "Bind Failed\n");    
            exit(2);
    }
else       printf("BindDone: %s\n", argv[1]);

//}




    if(listen(listenfd, 10) == -1)
    {
        printf("Failed to listen\n");
        return -1;
    }
else {   printf("ListenDone: %s\n", argv[1]);

}

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

        /* Open the file that we wish to transfer */
        FILE *fp = fopen(filename,"rb");
        if(fp==NULL)
        {

//checking if there is some problem with file or file present or not??

             fprintf(stderr, "%s", "File open error\n");    
            exit(3); 
        }   

        /* Read data from file and send it */
        while(1)
        {
            /* First read file in chunks of 256 bytes */
            unsigned char buff[256]={0};
            int nread = fread(buff,1,256,fp);
        byte_count +=nread;

          //  printf("Bytes read %d \n", nread);        

            /* If read was success, send data. */
            if(nread > 0)
            {
               // printf("Sending \n");
                write(connfd, buff, nread);
            }


            if (nread < 256)
            {
printf("TransferDone: %d bytes\n" ,byte_count);
                if (feof(fp)){

                    //printf("End of file\n");
}

if (ferror(fp))
                    printf("Error reading\n");
                break;
            }


        }

        close(connfd);
        sleep(1);
    //}


    return 0;
}

根据需要进行更改。