服务器和客户端数据 send() 和 recv() 问题

问题描述

我一直在尝试使用 C 套接字编程来编写一个客户端和服务器程序,它可以完成 2 个任务

  1. 在服务器提示时 -> 在客户端机器中执行 OS 命令
  2. 输出存储在发送回服务器的文件中。服务器读取它并显示数据并将数据写入服务器端的文件中。

问题 当客户端向服务器发送文件时,服务器不会显示完整的数据,看起来像 recv() 一直在等待套接字。

需要帮助

这是代码

服务器代码

#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>
#include <arpa/inet.h>
#define SIZE 1024

void write_file(char *filename,int sockfd){
  int n;
  FILE *fp ;
  char buffer[SIZE] ;
  
  fp = fopen(filename,"w");
  while (1) {
    n = recv(sockfd,buffer,SIZE,0);
    if (n <= 0){
      break;
      return;
    }
    printf("%s",buffer) ;
    fprintf(fp,"%s",buffer);
    bzero(buffer,SIZE);
  }
  fclose(fp) ;
  return;
}

int main(int argc,char *argv[]){
  
  int portno = 7416;
  int e,n,n1;
  char *cmd ;
  int sockfd;
  struct sockaddr_in server_addr;
  struct hostent *server;
  char *fle = "/tmp/reposvr.";
  FILE *fp;
  char *num ;
  
  
  if (argc < 3) {
     fprintf(stderr,"usage %s hostname command \n",argv[0]);
     exit(0);
  }
  cmd=argv[2] ;
  sockfd = socket(AF_INET,SOCK_STREAM,0);
  if(sockfd < 0) {
    perror("[-]Error in socket");
    exit(1);
  }
  printf("[+]Server socket created successfully.\n");
  server = gethostbyname(argv[1]);
  if (server == NULL) {
        fprintf(stderr,"ERROR,no such host\n");
        exit(0);
    }

  //server_addr.sin_family = AF_INET;
  //server_addr.sin_port = port;
  //server_addr.sin_addr.s_addr = inet_addr(ip);
  
  bzero((char *) &server_addr,sizeof(server_addr));
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(portno);
  server_addr.sin_addr = *((struct in_addr *)server->h_addr);
  memset(server_addr.sin_zero,'\0',sizeof server_addr.sin_zero);

  e = connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr));
  if(e == -1) {
    perror("[-]Error in socket");
    exit(1);
  }
    printf("[+]Connected to Server.\n");
    
   n = write(sockfd,cmd,strlen(cmd));
    if (n < 0) 
         error("ERROR writing to socket");
     
    char *filename=NULL;
    filename = (char*)malloc( 50 * sizeof(char) ) ;
    strcpy(filename,fle );
     
    n1=rand();   

    if (asprintf(&num,"%d",n1) == -1) {
        perror("asprintf");
    } else {
        strcat(filename,num);
        printf("%s\n",filename);
        free(num);
    }
     printf("%s\n",filename) ;
  

  write_file(filename,sockfd) ;
  printf("[+]File data sent successfully.\n");

    printf("[+]Closing the connection.\n");
  close(sockfd);

  return 0;
}

客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#define SIZE 1024

void send_file(FILE *fp,int sockfd){
  int n;
  char data[SIZE] = {0};

  while(fgets(data,fp) != NULL) {
    if (send(sockfd,data,sizeof(data),0) == -1) {
      perror("[-]Error in sending file.");
      exit(1);
    }
    bzero(data,SIZE);
  }
}

int main(){
  int port = 7416;
  int e,n1,n ;  
  FILE *fp ;
  char filename[50] = "/tmp/gateway." ;
  char command[50];
  char *num;
  FILE *pf;
  char data[SIZE];
  int sockfd,new_sock;
  struct sockaddr_in server_addr,new_addr;
  socklen_t addr_size;
  char buffer[SIZE];

  sockfd = socket(AF_INET,0);
  if(sockfd < 0) {
    perror("[-]Error in socket");
    exit(1);
  }
  printf("[+]Server socket created successfully.\n");

  server_addr.sin_family = AF_INET;
  server_addr.sin_port = htons(port);
  server_addr.sin_addr.s_addr = INADDR_ANY;

  e = bind(sockfd,sizeof(server_addr));
  if(e < 0) {
    perror("[-]Error in bind");
    exit(1);
  }
  printf("[+]Binding successfull.\n");

  if(listen(sockfd,10) == 0){
        printf("[+]Listening....\n");
    }else{
        perror("[-]Error in listening");
    exit(1);
    }

  addr_size = sizeof(new_addr);
  while ( new_sock = accept(sockfd,(struct sockaddr*)&new_addr,&addr_size) )
  {   
       printf("server: got connection from %s port %d\n",inet_ntoa(new_addr.sin_addr),ntohs(new_addr.sin_port));
              
       n = read(new_sock,1024);
       if (n < 0) error("ERROR reading from socket");
     
         strcpy(command,buffer) ;
         printf("%s",command) ;
         pf = popen(command,"r");
         bzero(data,1024);
        n1=rand();   
         
    

    if (asprintf(&num,filename);
        free(num);
    }
     printf("%s",filename) ;
     fp=fopen(filename,"w" );
     while (fgets(data,2048,pf) != NULL) {
        printf("%s",data);
        fprintf(fp,data) ;
        }
        fclose(fp) ;
      fp = fopen(filename,"r");
  if (fp == NULL) {
    perror("[-]Error in reading file.");
    exit(1);
  }
  
   send_file(fp,new_sock);
   printf("[+]Data written in the file successfully.\n");
  }
  
  

  return 0;
  
}

执行输出

enter image description here

编辑

根据本论坛的建议,我将 SIZE 增加到 2048,发现现在返回的行数减少了,并且在 4-5 行后挂起。这很奇怪。我确定这不是因为 SIZE。

如果您看到,在客户端,我们能够成功地将所有内容写入文件。程序的第二部分是从文件中读取并将其发送到服务器。在这里,我遍历整个文件并将数据发送到服务器。数据发送循环运行良好,因为我在同一个循环中使用了 printf,我们可以看到所有数据都被打印出来。

在服务器端,我们也在循环直到读取的字节数

编辑 2 正如您在评论中看到的,已经尝试过 SIZE 、 MSG_PEEK 。还有什么建议吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)