【问题标题】:C recv function behaviorC recv 函数行为
【发布时间】:2023-03-17 16:31:01
【问题描述】:

这是我的两段代码:

服务器.c

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

#define BYTES_NR 64
#define MSG_NR 512

int main(int argc, char *argv[]) {
    char buf[BYTES_NR];
    int sock,length;
    struct sockaddr_in server,client;
    int rval,i;


    if(argc !=2) {
        fprintf(stderr,"Usage: %s port\n",argv[0]);
        exit(-1);
    }

    sock = socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0) {
        perror("opening stream socket");
        exit(1);
    }

    server.sin_family = AF_INET;
    server.sin_addr.s_addr= INADDR_ANY;
    server.sin_port = htons(atoi(argv[1]));
    if (bind(sock,(struct sockaddr *)&server,sizeof(server))<0) {
        perror("binding stream socket");
        exit(1);
    }

    length = sizeof(server);
    if(getsockname(sock,(struct sockaddr *)&server, (socklen_t *)&length)<0){
        perror("getting socket name");
        exit(1);
    }


    printf("Socket port #%d\n",ntohs(server.sin_port));
        printf("test");
    while(1) {
        do {
        printf("test2");
            bzero(buf,sizeof(buf));
            rval = recvfrom(sock,buf,sizeof(buf), 0, (struct sockaddr *)&client, (socklen_t *)&length );

            if(rval<0)
                perror("reading stream message");
            i=0;
            if(rval==0)
                printf("Ending connection\n");
            else {
                printf("Message received: sending back\n");
                strcat(buf,"*");
                if (sendto(sock,buf,sizeof(buf),0,(struct sockaddr *)&client,sizeof(client))<0)
                    perror("writing on stream socket");
            }
        } while(rval !=0);
    }
    return 0;
}

client.c

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

#define BYTES_NR 64
#define MSG_NR 512


int main(int argc, char *argv[]) {
    char buf[BYTES_NR];
    char buf2[BYTES_NR];
    char msg[MSG_NR][BYTES_NR];
    char answ[MSG_NR][BYTES_NR];
    struct timeval xstime[MSG_NR];
    struct timeval xftime[MSG_NR];
    int i,sock,rval,length;
    unsigned long delay;
    struct sockaddr_in server,client;
    struct hostent *hp, *gethostbyname();

    if(argc !=3) {
        fprintf(stderr,"Usage: %s servername serverport\n",argv[0]);
        exit(-1);
    }

    for(i=0;i<MSG_NR;i++) {
        sprintf(&msg[i][0],"%d",i);
    }

    sock= socket(AF_INET,SOCK_DGRAM,0);
    if(sock<0) {
        perror("opening stream socket");
        exit(1);
    }

    client.sin_family= AF_INET;
    client.sin_addr.s_addr = INADDR_ANY;
    client.sin_port = htons(0);

    if (bind(sock,(struct sockaddr *)&client,sizeof(client)) <0) {
        perror("sending datagram message");
        exit(1);
    }

    length= sizeof(client);
    if(getsockname(sock,(struct sockaddr *)&server,(socklen_t *)&length)<0) {
        perror("getting socket name");
        exit(1);
    }

    printf("Socket port #%d\n",ntohs(client.sin_port));
    hp = gethostbyname(argv[1]);
    if (hp == 0) {
        fprintf(stderr,"%s :unknow host",argv[1]);
        exit(2);
    }

    bcopy( (char *)hp ->h_addr, (char *)&server.sin_addr,hp ->h_length);
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    for(i=0;i<MSG_NR;i++) {
    printf("ciclo-");
        strcpy(buf,msg[i]);
        gettimeofday(&xstime[i],NULL);

        if(sendto(sock, buf, sizeof(buf), 0, (struct sockaddr *)&server, sizeof(server)) < 0)
            perror("sendto problem");

        if((rval = read(sock,buf2,sizeof(buf2)))<0)
            perror("reading stream message");

        strcpy(answ[i],buf2);
        gettimeofday(&xftime[i],NULL);
    }
    close(sock);

    for (i=0; i<MSG_NR; i++) {
        delay = (xftime[i].tv_sec-xstime[i].tv_sec)*1000000.+(xftime[i].tv_usec-xstime[i].tv_usec);
        printf("msg %d [%s]: %0.3f ms\n",i,answ[i],delay/1000.);
    }

    return 0;
}

在服务器端,为什么打印“test”的 printf 在客户端到达发送消息的请求之前没有运行?打印“test2”的第二个 printf 也是如此。 可能有一些概念让我无法理解!

如果我评论 recv ,则执行流程返回正常。

【问题讨论】:

  • strcat(buf,"*"); 你假设 buf 是空终止的并且足够大。不是和/或不是。
  • 这只是一个测试代码,但我唯一的疑问是关于行缓冲区标准输出!
  • 我不在乎是什么。这是错误的。 bzero(buf,sizeof(buf)); 触发了我的感官。 if(rval&lt;0) perror("reading stream message"); 也应该检查 EAGAIN 的 errno(可能还有其他一些)。
  • BTW '#define BYTES_NR 64 #define MSG_NR 512` 和 char msg[MSG_NR][BYTES_NR];(和其他)对于您的自动存储来说可能太大了。 (“堆栈”)

标签: c sockets recv recvfrom


【解决方案1】:

这与recv 无关。改为:

printf("test\n");

默认情况下,stdout 是行缓冲的,因此在打印换行符之前您什么都看不到。

如果您不想打印换行符,可以在每个printf 之后使用fflush(stdout); 来打印当前缓冲区。您还可以使用:

setvbuf(stdout, NULL, _IONBF, BUFSIZ);

禁用输出缓冲。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 2014-05-05
    相关资源
    最近更新 更多