Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用C&;实现停止和等待;UDP,以及是什么导致';资源暂时不可用';?_C_Sockets_Udp_Recvfrom - Fatal编程技术网

使用C&;实现停止和等待;UDP,以及是什么导致';资源暂时不可用';?

使用C&;实现停止和等待;UDP,以及是什么导致';资源暂时不可用';?,c,sockets,udp,recvfrom,C,Sockets,Udp,Recvfrom,我正在用c和udp套接字编程实现停止&等待。为了模拟这个协议,我编写了两个代码 这是我的server.c文件: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #inclu

我正在用c和udp套接字编程实现停止&等待。为了模拟这个协议,我编写了两个代码

这是我的
server.c
文件:

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


typedef struct packet{
    char data[1024];
}Packet;

typedef struct frame{
    int frame_kind; //ACK:0, SEQ:1 FIN:2
    int sq_no;
    int ack;
    Packet packet;
}Frame;

int main(int argc, char** argv)
{
    int sockfd;
    int clilen;
    int state;
    int n;
    int sum;
    int recv_result;

    int frame_id = 0;

    Packet packet;
    Frame frame;
    Frame recv_frame;
    char buffer[1024] = "";

    struct timeval tv;

    struct sockaddr_in serveraddr, clientaddr;

    FILE* infile = fopen(argv[2], "r");
    if(argc != 3)
    {
        perror("error! usage: $./server <PORT> filename\n");
        exit(1);
    }
    if(infile == NULL)
    {
        printf("error! failed to open the file.\n");
        exit(0);
    }

    clilen = sizeof(clientaddr);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0); //using diagram instead of stream-- UDP
    if(sockfd < 0)
    {
        perror("socket error: ");
        exit(0);
    }

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons(atoi(argv[1])); //set port number 9999

    //set socket option -- timeout is 100000 microseconds

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval));

    state = bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
    if(state == -1)
    {
        perror("bind error: ");
        exit(0);
    }

    do{
        n = fscanf(infile, "%s", buffer);

        strcpy(packet.data, buffer);
        memcpy(&(frame.packet), &packet, sizeof(Packet));
        frame.frame_kind = 1; //SEQ
        frame.sq_no = frame_id;
        frame.ack = 0;
        printf("flag2");
        while(1)
        {
            sendto(sockfd, &frame, sizeof(frame), 0, (struct sockaddr*)&clientaddr, (socklen_t)clilen);
            printf("Frame %d sent\n", frame_id);
            recv_result = recvfrom(sockfd, &recv_frame, sizeof(recv_frame), 0,(struct sockaddr*)&clientaddr, &clilen );

            if(recv_result > 0 && recv_frame.sq_no == 0 && recv_frame.ack == frame_id){
                printf("Ack %d received\n", recv_frame.sq_no);
                break;
            }else{
                printf("Frame %d time expired\n", frame_id);
            }
        }
        frame_id++;
    }while(n > 0);

    printf("finished\n");
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

typedef struct packet{
    char data[1024];
}Packet;

typedef struct frame{
    int frame_kind; //ACK:0, SEQ:1 FIN:2
    int sq_no;
    int ack;
    Packet packet;
}Frame;

int main(int argc, char *argv[])
{
    int sock;
    int str_len;
    socklen_t adr_sz;
    FILE* outfile = fopen("output.txt", "w");
    struct sockaddr_in serv_adr, from_adr;
    Frame ackframe, recv_frame;
    int frame_id;
    int recv_result;
    struct timeval tv;

    if(argc!=3){
        printf("Usage : %s <IP> <port>\n", argv[0]);
        exit(1);
    }
    sock=socket(PF_INET, SOCK_DGRAM, 0);   
    if(sock==-1)
    {
        printf("error! failed to open the socket\n");
        exit(1);
    }

    memset(&serv_adr, 0, sizeof(serv_adr));
    adr_sz = sizeof(serv_adr);
    serv_adr.sin_family=AF_INET;
    serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_adr.sin_port=htons(atoi(argv[2]));

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval));

    frame_id = 0;
    while(1)
    {
        recv_result = recvfrom(sock, &recv_frame, sizeof(recv_frame), 0,(struct sockaddr*)&serv_adr, &adr_sz);
        perror("error: ");
        printf("data %s\n", recv_frame.packet.data);
        printf("recv result %d\n", recv_result);
        printf("recv frame=%d, frame_kind = %d\n", recv_frame.sq_no, recv_frame.frame_kind);
        if(recv_result > 0 && recv_frame.frame_kind == 1 && recv_frame.sq_no==frame_id){
            printf("Frame %d received\n", recv_frame.sq_no);
            fprintf(outfile, "%s", recv_frame.packet.data);
            ackframe.frame_kind = 0;
            ackframe.ack = recv_frame.sq_no + 1;
            printf("Ack %d sent\n", ackframe.ack);
            sendto(sock, &recv_frame, sizeof(recv_frame), 0,(struct sockaddr*)&serv_adr, adr_sz);


            break;
        }else{
            printf("Frame %d time expired\n", frame_id);
        }
    }   
    close(sock);
    fclose(outfile);
    return 0;
}
服务器需要3个参数:
/server

客户端还需要3个参数:
/client

它被执行,但客户端的
recvfrom
始终返回
-1

我读了一些主题相同的问题,但无法从代码中找出错误。有没有办法用
recvfrom
sendto
修复我的代码?或者我需要使用
select
功能吗?(我将只与一台服务器和一台客户端通信。)

该“客户端”和“服务器”程序包含一些可疑代码。首先让我们看一看“服务器”,它使用您尚未初始化的
clientaddr
调用
sendto
。谁知道你想把包送到哪里。事实上,这会导致未定义的行为,因为结构的内容是不确定的

然后让我们以客户机为例,在该客户机中,您在未绑定本地的套接字上调用
recvfrom
。传递给
recvfrom
的地址结构指针由
recvfrom
函数填充,但其中的数据不以任何其他方式使用


可能还有其他问题,但这两个问题很突出。

您确实意识到,
fread()
不会以null终止它所读取的内容吗?哦,我在最新的代码中修复了它,但没有修复其中一个代码。但我不认为这是“资源暂时不可用”错误的原因。考虑到您
strcpy()
一些可能不是以null结尾的内容,然后您
memcpy()
相同的内容,我不想为您调试此代码。如果像return
-1
这样的系统调用,那么您可以(并且应该)调试此代码看看哪里出了问题。另外,
errno
的值是未定义的,如果上一个函数没有实际失败,请不要选中
errno
,除非上一个函数实际失败。您会收到该错误,因为您可能已将超时设置为低超时。如果没有要接收的内容,则
recvfrom
函数将超时并返回该错误。至于为什么什么都没有收到是一个完全不同的故事,可能有100个不同的原因,但在快速浏览您的代码后,您的程序似乎有点不正常,我将在回答中解释更多。我修复了它。原因是……)