C recv函数行为

时间:2014-06-02 22:03:27

标签: c sockets recv recvfrom

这是我的两段代码:

server.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;
}

在服务器端,为什么printf打印&#34; test&#34;在客户端收到请求发送消息之前没有运行?对于打印&#34; test2&#34;的第二个printf也是如此。 可能有些概念让我感到惊讶!

如果我评论recv,执行流程将恢复正常。

1 个答案:

答案 0 :(得分:2)

这与recv无关。改为:

printf("test\n");

默认情况下,stdout是行缓冲的,因此在打印换行符之前,您不会看到任何内容。

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

setvbuf(stdout, NULL, _IONBF, BUFSIZ);

禁用输出缓冲。