有关网络编程文件传输问题

网络编程 文件传输
当客户端与服务端连接后,想完成客户端输入命令ls 服务端列出当前文件夹下的所有文件,输入命令download 文件名 ,服务端将该文件发送给客户端。代码如下,1.为什么客户端输入ls后,会没有反应,2.至于download命令,想用通配符 * ,再分解输入的字符串,得到空格后的文件名,也没有反应,为什么,应该怎么修改?谢谢

//server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dirent.h>
#include<fcntl.h>
#define BUFFER_SIZE 1024
void list_dir(int sockfd) 
{
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, sizeof(buffer));
    DIR *dir;
    struct dirent *entry;
    struct stat file_stat;
    if ((dir = opendir(".")) == NULL) 
    {
        printf(buffer, "无法打开目录\n");
        if (send(sockfd, buffer, strlen(buffer), 0) < 0) 
        {
            perror("send error");
            exit(EXIT_FAILURE);
        }
        return;
    }    
    /*while ((entry = readdir(dir)) != NULL)
    {
        if (entry->d_name[0] != '.')
        {
            char size_str[20];
            if (stat(entry->d_name, &file_stat) == -1) 
            {
                printf(size_str, "未知大小");
            } else {
                printf(size_str, "%ld bytes", file_stat.st_size);
            }
            printf(buffer + strlen(buffer), "%-20s %s\n", entry->d_name, size_str);
        }
    }*/
    if (send(sockfd, buffer, strlen(buffer), 0) < 0) 
    {
        perror("send error");
        exit(EXIT_FAILURE);
    }
}

void download(int sockfd, char* filename) {
    char buff[1024]= {0};
    //1.打开文件
    int fd = open(filename,O_RDONLY,1000);
    if(-1==fd)
        {
            printf("文件打开失败");
        }
    //2.将文件发送给服务器
    while(1){
        int r= read(fd,buff,1024);
        if(r>0)
            send(sockfd,buff,r,0);
        else
            break;
        }
}

int main(int argc, char *argv[]) 
{
    char str[100];
    char *pos;
    // 创建socket
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) 
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }    
    // 设置服务端地址
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr)); //结构体初始化
    servaddr.sin_family = AF_INET;
    // servaddr.sin_port = htons(argv[2]);
    servaddr.sin_port = htons(atoi(argv[1]));
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    // 绑定端口
    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) 
    {
        perror("bind error");
        exit(EXIT_FAILURE);
    }
    // 监听端口
    if (listen(listenfd, 5) < 0) 
    {
        perror("listen error");
        exit(EXIT_FAILURE);    
    }
    printf("服务端已启动,等待客户端连接...\n");
    // 循环接收客户端连接
    int connfd;
    struct sockaddr_in cliaddr;  //
    memset(&cliaddr, 0, sizeof(cliaddr));
    socklen_t clilen = sizeof(cliaddr);
    while (1)
    {
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
        if (connfd < 0) 
        {
            perror("accept error");
            continue;
        }
        printf("客户端 %s:%d 已连接\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));//ip地址和端口号?
        // 发送欢迎信息
        char buffer[BUFFER_SIZE];
        memset(buffer, 0, sizeof(buffer));
        sprintf(buffer, "欢迎连接到服务端!");
        if (send(connfd, buffer, strlen(buffer), 0) < 0) 
        {
            perror("send error");
            exit(EXIT_FAILURE);
        }
        // 循环接收命令并执行
        while (1) 
        {
            memset(buffer, 0, sizeof(buffer));
            if (recv(connfd, buffer, sizeof(buffer), 0) < 0)
            {
                perror("recv error");
                exit(EXIT_FAILURE);
            }
            if (strcmp(buffer, "exit") == 0) 
            {
                printf("客户端 %s:%d 已断开连接\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
                break;
            } else if (strcmp(buffer, "ls") == 0) {
                list_dir(connfd);
            } else if(strcmp(buffer,"download *")==0){
                 fgets(str, 100, stdin);
                  pos = strchr(str, ' ');
                  if (pos != NULL) 
                  {
                      printf("空格后的字符串为:%s", pos + 1);
                      download(connfd,pos+1);
                  } 
                  else
                  {
                      printf("请输入正确的文件格式");
                  }
            }
            else {
                printf(buffer, "未知命令:%s\n", buffer);
                if (send(connfd, buffer, strlen(buffer), 0) < 0) 
                {
                    perror("send error");
                    exit(EXIT_FAILURE);
                }
            }
        }
        // 关闭客户端连接
        close(connfd);
    }
    // 关闭socket
    close(listenfd);
    return 0;
}

//client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 1024
int main(int argc, char *argv[]) {    
  // 创建socket    
 int sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0) {        perror("socket error");        exit(EXIT_FAILURE);    }    
  // 设置服务端地址    
 struct sockaddr_in servaddr;    
 memset(&servaddr, 0, sizeof(servaddr));    
 servaddr.sin_family = AF_INET;    
 servaddr.sin_port = htons(atoi(argv[1]));    
 servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");    
  // 连接服务端    
 if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)  
  {        
  perror("connect error");         
  exit(EXIT_FAILURE);    
  }    
  // 接收服务端欢迎信息    
 char buffer[BUFFER_SIZE];     
 memset(buffer, 0, sizeof(buffer));    
 if (recv(sockfd, buffer, sizeof(buffer), 0) < 0)  
  {        
  perror("recv error");        
  exit(EXIT_FAILURE);    
 }    
 printf("%s\n", buffer);    
  // 循环输入命令并接收回复    
 while (1)  
 {        
   printf("请输入命令:");         
   memset(buffer, 0, sizeof(buffer));        
   fgets(buffer, sizeof(buffer), stdin);        
   buffer[strlen(buffer) - 1] = '\0';        
   if (send(sockfd, buffer, strlen(buffer), 0) < 0)  
         {            
      perror("send error");            
      exit(EXIT_FAILURE);        
         }        
   if (strcmp(buffer, "exit") == 0) 
        {            
     printf("客户端已退出\n");    
     break;
        }
   memset(buffer, 0, sizeof(buffer));
   if (recv(sockfd, buffer, sizeof(buffer), 0) < 0) 
       {
      perror("recv error");
      exit(EXIT_FAILURE);
       }
   printf("%s\n", buffer);
  }    
  // 关闭socket    
 close(sockfd);    
 return 0;
}

在你最新的问题中的代码上进行了修改。
运行结果:

img

server代码:

//server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <dirent.h>
#include<fcntl.h>
#define BUFFER_SIZE 1024
void list_dir(int sockfd)
{
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, sizeof(buffer));
    DIR *dir;
    struct dirent *entry;
    if ((dir = opendir(".")) == NULL)
    {
        sprintf(buffer, "无法打开目录\n");
        if (send(sockfd, buffer, strlen(buffer), 0) < 0) {
            perror("send error");
            exit(EXIT_FAILURE);
        }
        return;
    }
    while ((entry = readdir(dir)) != NULL)
    {
        if (entry->d_name[0] != '.')
        {
            strcat(buffer, entry->d_name);
            strcat(buffer, "\n");
        }
    }
    if (send(sockfd, buffer, strlen(buffer), 0) < 0)
    {
        perror("send error");
        exit(EXIT_FAILURE);
    }
}

int main(int argc, char *argv[])
{
    char str[100];
    char *pos;
    ssize_t n;
    FILE *fp;
    char buffer[BUFFER_SIZE];
    // 创建socket
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0)
    {
        perror("socket error");
        exit(EXIT_FAILURE);
    }
    // 设置服务端地址
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr)); //结构体初始化
    servaddr.sin_family = AF_INET;
    // servaddr.sin_port = htons(argv[2]);
    servaddr.sin_port = htons(atoi(argv[1]));
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    // 绑定端口
    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    {
        perror("bind error");
        exit(EXIT_FAILURE);
    }
    // 监听端口
    if (listen(listenfd, 5) < 0)
    {
        perror("listen error");
        exit(EXIT_FAILURE);
    }
    printf("服务端已启动,等待客户端连接...\n");
    // 循环接收客户端连接
    int connfd;
    struct sockaddr_in cliaddr;
    memset(&cliaddr, 0, sizeof(cliaddr));
    socklen_t clilen = sizeof(cliaddr);

    connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
    if (connfd < 0)
    {
        perror("accept error");
    }
    printf("客户端 %s:%d 已连接\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));//ip地址和端口号?
    // 发送欢迎信息
    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, "欢迎连接到服务端!");
    if (send(connfd, buffer, strlen(buffer), 0) < 0)
    {
        perror("send error");
        exit(EXIT_FAILURE);
    }
    // 循环接收命令并执行
    while (1)
    {
        n = read(connfd, buffer, sizeof(buffer));
        //memset(buffer, 0, sizeof(buffer));
        printf("receved[%d bytes]:%s\n",n,buffer);
        if(n > 0)
        {
            printf("deal %s...\n",buffer);
            buffer[n]='\0'; //mod
            if (strcmp(buffer, "exit") == 0)
            {
                printf("客户端 %s:%d 已断开连接\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
                break;
            } else if (strcmp(buffer, "ls") == 0)
            {
                list_dir(connfd);
            } else if(strncmp(buffer,"download ",9)==0)
            {
                char *filename = buffer + 9;
                filename[strlen(filename)-1]='\0';
                //recv(connfd,str,1024,MSG_DONTWAIT);
                //pos = strchr(str, ' ');
                // 打开文件
                fp = fopen(filename, "rb");
                if (fp == NULL)
                {
                    // 文件不存在
                    strcpy(buffer, "File not found!\n");
                    write(connfd, buffer, strlen(buffer));
                } else
                {
                    // 读取文件并发送给客户端
                    while ((n = fread(buffer, 1, 1024, fp)) > 0)
                    {
                        write(connfd, buffer, n);
                    }
                    fclose(fp);
                }
            } else {
                // 不支持的命令
                strcpy(buffer, "Unsupported command!\n");
                write(connfd, buffer, strlen(buffer));
            }
        }
        else
        {
            perror("recv error");
            exit(1);
        }

        // 关闭客户端连接
        close(connfd);
    }
    // 关闭socket
    close(listenfd);
    return 0;
}


您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632