【问题标题】:UDP File transfer in CC语言中的UDP文件传输
【发布时间】:2020-12-26 19:46:32
【问题描述】:

我正在开发一个套接字编程的东西,用于在 C 中通过 UDP 实现文件传输。服务器和客户端代码都在没有报告任何错误的情况下执行:当我运行代码时,两个套接字都被创建并绑定,我'被提示在客户端输入文件名。但是在我进入它之后,什么都没有发生。双方都保持空白,而我应该在服务器端获得“收到文件名”输出,然后提示输入加密密钥。我不明白,我不知道为什么。我尝试了几次代码迭代,甚至在线尝试了代码建议,但我没有运气。有什么问题?

这是服务器代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define SA struct sockaddr
#define PORT 12345
#define SIZE 256
#define EMP "the file does not exist"

char encrypt(char c, char k){

    return c ^ k;
}

int sendfl(FILE *fp, char *buff, int l, char k){

    int i, len;

    if(fp == NULL){

        strcpy(buff, EMP);
        len = strlen(EMP);
        buff[l] = EOF;

        for(i = 0; i < len; i++)
            buff[i] = encrypt(buff[i], k);
            return 1;
    }

    char c1, c2;

    for(i = 0; i < l; i++) {
        c1 = fgetc(fp);
        c2 = encrypt(c1, k);
            buff[i] = c2;
    if(c1 == EOF)
        return 1;
    }

        return 0;

}

int main(){

    int sockid, len, e, n;
    char key;
    char flname[SIZE];
    char buff[SIZE];    
    FILE *fp;
    struct sockaddr_in servaddr;

    len = sizeof(servaddr);

    sockid = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockid < 0){
        perror("failed to create socket");
            exit(0);
    }
    printf("socket created! \n");

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = INADDR_ANY;

    e = bind(sockid, (SA*)&servaddr, len);
    if(e == -1){
        perror("failed to bind");
        exit(1);
    }
    printf("bind successful, \n");

    while (1) {

        printf("waiting for file name... \n");

        bzero(flname, SIZE);

        n = recvfrom(sockid, flname, sizeof(flname), 0, (SA*)&servaddr, &len);
        printf("file name recieved \t%s\n", flname);

        fp = fopen(flname, "r");
        if(fp == NULL){
            perror("failed to open file");
            exit(1);
        }
        printf("file opened...");

        printf("enter encryption key \t");
        scanf("%c\n", &key);

        while (1) {

            if(sendfl(fp, buff, SIZE, key)){
                sendto(sockid, buff, SIZE, 0, (SA*)&servaddr, len);
                break;
            }

             sendto(sockid, buff, SIZE, 0, (SA*)&servaddr, len);
             bzero(buff, SIZE);
        }

        if(fp != NULL)
        fclose(fp);
         }

    return 0;
}

这是客户端代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define SA struct sockaddr
#define PORT 12345
#define IPA "127.0.0.1"
#define SIZE 256
#define EMP "the file does not exist"

char decrypt(char c, char k){

    return c ^ k;
}

int recfl(char *buff, int l, char k){

    int i;
    char c1, c2;

    for(i = 0; i < l; i++) {
        c1 = buff[i];
        c2 = decrypt(c1, k);
    if(c2 == EOF)
        return 1;
    else
        printf("%c", c2);
    }

        return 0;
}

int main(){

    int sockid, len, n;
    char key;
    char flname[SIZE];
    char buff[SIZE];    
    FILE *fp;
    struct sockaddr_in servaddr;

    len = sizeof(servaddr);

    sockid = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockid < 0){
        perror("failed to create socket");
            exit(0);
    }
    printf("\nsocket created!\n");

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = inet_addr(IPA);

    while (1) {

        bzero(flname, SIZE);

        printf("\nenter file name:\t");
        scanf("%s\n", flname);

        sendto(sockid, flname, sizeof(flname), 0, (SA*)&servaddr, len);
        printf("\nfile recieved\n");

        printf("\nenter encryption key\t");
        scanf("%c\n", &key);

        printf("\n--------------------DATA RECIEVED--------------------\n");

        while (1) {

             bzero(buff, SIZE);
             n = recvfrom(sockid, buff, SIZE, 0, (SA*)&servaddr, &len);

            if(recfl(buff, SIZE, key)){
                
                break;
            }

        }

        printf("\n-----------------------------------------------------\n");
        }

    return 0;
}

【问题讨论】:

  • 试试scanf("%c\n", &amp;key); --> scanf(" %c", &amp;key); ImTheShell,你觉得scanf("%c\n", &amp;key); 有什么作用?
  • 老实说,我不确定它有什么作用,哈哈,我的意思是……没有空间,但是是的,我会用额外的空间来试一试。感谢您的建议

标签: c sockets udp runtime-error runtime


【解决方案1】:

首先你忽略了\nscanf("%s\n", flname) 中的作用;这是来自 C 标准的描述:

由空白字符组成的指令通过读取输入执行到 第一个非空白字符(仍然未读),或者直到没有更多字符可以 被阅读。

因此,等待更多输入就是您认为的没有其他事情发生

结合 chux 的建议,如果您删除 \n,您会更进一步。

【讨论】:

  • 非常感谢您的帮助!这就是问题所在,在我删除 /n 并调整了 scanf 在循环中的位置之后,程序完美地运行了!再次感谢大家的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多