为什么我在 C 中得到一个意外的端口值?
Why do I get an unexpected port value in C?
我正在编写一个程序,它从参数中获取标识符、创建 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;
}
}
如果按原样使用,您的代码会崩溃。因为你传递给 realloc 未初始化的指针。将 processes
初始化为 NULL:
process * processes = NULL;
编辑:
否则,udp_port 不为零。并且 getsockname
returns 地址错误。
为 getsockname
尝试以下操作以取得成功:
socklen_t tmp = sizeof(struct sockaddr);
getsockname (fd, (struct sockaddr *) &local_addr,&tmp);
检查 getsockname
函数的 return 值时出现 Bad address
错误。
问题是 getsockname
中的最后一个参数不正确:
getsockname(fd, (struct sockaddr *)&local_addr, (socklen_t *) sizeof(struct sockaddr));
sizeof
return 是 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;
}
我正在编写一个程序,它从参数中获取标识符、创建 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;
}
}
如果按原样使用,您的代码会崩溃。因为你传递给 realloc 未初始化的指针。将 processes
初始化为 NULL:
process * processes = NULL;
编辑:
否则,udp_port 不为零。并且 getsockname
returns 地址错误。
为 getsockname
尝试以下操作以取得成功:
socklen_t tmp = sizeof(struct sockaddr);
getsockname (fd, (struct sockaddr *) &local_addr,&tmp);
检查 getsockname
函数的 return 值时出现 Bad address
错误。
问题是 getsockname
中的最后一个参数不正确:
getsockname(fd, (struct sockaddr *)&local_addr, (socklen_t *) sizeof(struct sockaddr));
sizeof
return 是 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;
}