为什么我在C中获得意外的端口值?

时间:2015-05-19 17:43:20

标签: c sockets memory dynamic

我编写的程序从params获取标识符,创建UDP套接字,获取端口并打印<identifier>: <port>
然后,从stdin接收一些标识符和端口并将它们存储在内存中。
在下面的代码中,问题是端口变量(udp_port)得到0。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

typedef struct process {
    char id[80];
    int port;
    int me;
} process;

int main(int argc, char* argv[]) {

    if(argc<2) {
        fprintf(stderr,"Use: process <ID>\n");
        return 1;
    }

    /* NODES */
    process * processes;
    int num_process = 0;

    /* CONECTION */
    int udp_port;
    int fd;
    struct sockaddr_in addr, local_addr;

    /* STDIN READS */
    int port;
    char line[80],proc[80];

    /* I/O buffer mode */
    setvbuf(stdout,(char*)malloc(sizeof(char)*80),_IOLBF,80); 
    setvbuf(stdin,(char*)malloc(sizeof(char)*80),_IOLBF,80); 

    /* Prepare socket */
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(0);
    addr.sin_addr.s_addr = INADDR_ANY;

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd == -1){
        perror("SOCKET");
        return 1;
    }

    if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1){
        perror("BIND");
        return 1;
    }
    getsockname(fd, (struct sockaddr *)&local_addr, (socklen_t *) sizeof(struct sockaddr));

    udp_port=ntohs(local_addr.sin_port);   // Gets port

    fprintf(stdout,"%s: %d\n",argv[1],udp_port);   // Prints identifier: port

    // Reads from stdin
    for(;fgets(line,80,stdin);) {
        if(!strcmp(line,"START\n"))
            break;            

        sscanf(line,"%[^:]: %d",proc,&port);
        num_process++;
        processes = realloc(processes,num_process);
        strcpy(processes[num_process-1].id, proc);
        processes[num_process-1].port = port;

        if(!strcmp(proc,argv[1])){ /* Thats me */
            processes[num_process-1].me = 1;
        }else{
            processes[num_process-1].me = 0;
        }
    }   


  return 0;
}

但是,当我评论realloc行和相关行时,它得到一个正确的值(随机端口),如下所示:

    // Reads from stdin
    for(;fgets(line,80,stdin);) {
        if(!strcmp(line,"START\n"))
            break;            

        sscanf(line,"%[^:]: %d",proc,&port);
        num_process++;
        //processes = realloc(processes,num_process);
        //strcpy(processes[num_process-1].id, proc);
        //processes[num_process-1].port = port;

        if(!strcmp(proc,argv[1])){ /* Thats me */
        //    processes[num_process-1].me = 1;
        }else{
        //    processes[num_process-1].me = 0;
        }
    }   

2 个答案:

答案 0 :(得分:1)

如果按原样使用,您的代码会崩溃。因为你传递给realloc未初始化的指针。将processes初始化为NULL:

process * processes = NULL;

编辑:

否则,udp_port不为零。 getsockname返回Bad地址。 请尝试以下getsockname成功:

socklen_t tmp = sizeof(struct sockaddr);

getsockname (fd, (struct sockaddr *) &local_addr,&tmp);

答案 1 :(得分:0)

检查getsockname函数的返回值我收到Bad address错误。 问题是getsockname中的最后一个参数不正确:

getsockname(fd, (struct sockaddr *)&local_addr, (socklen_t *) sizeof(struct sockaddr));

sizeof返回socklen_t而不是socklen_t *。我这样解决了这个问题:

socklen_t size_sa = sizeof(struct sockaddr);
if(getsockname(fd, (struct sockaddr *)&local_addr, &size_sa) == -1){
    perror("GETSOCKNAME");
    return 1;
}