我目前正致力于将公开的输入管道程序与Packet Forwarder一起用于自定义网络。
此转发器在启动期间获取配置文件,并通过网络转发指定的端口。
我现在的问题如下:
当我运行inputpipe客户端(连接USB设备的PC)和服务器(USB设备被模拟的PC)时,我可以指定服务器将监听的端口。 (服务器然后在该特定端口上绑定()和listen())。
我现在的问题是客户端将创建socket(),然后通过IP地址和远程端口连接()到服务器。在此过程中,客户端的操作系统会将一个随机端口号分配给它所连接的套接字。
由于我需要在实际运行服务器之前指定转发器的传出端口,这使得它无法实现。我在connect()之前尝试了bind()套接字,但这只在目标和源机器相同时(通过localhost连接时)才有效,并且在使用实际的单独机器时不起作用。
长话短说:有没有办法为套接字指定远程端口和本地端口?
编辑:我的代码无论出于何种原因都无效:
struct sockaddr_in in_addr;
/* Struct for the bind call
*/
struct sockaddr_in out_addr;
/*
*/
struct hostent* host;
int fd;
int opt = 1;
/* Allocate the new server object */
self = malloc(sizeof(struct server));
assert(self != NULL);
memset(self, 0, sizeof(struct server));
/* Parse the host:port string */
self->host = strdup(host_and_port);
self->port = IPIPE_DEFAULT_PORT;
p = strchr(self->host, ':');
if (p) {
*p = '\0';
self->port = atoi(p+1);
}
/* New socket */
fd = socket(PF_INET, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
server_delete(self);
return NULL;
}
/* Bind the socket to remote port +1 */
memset(&out_addr, 0, sizeof(out_addr));
out_addr.sin_family = AF_INET;
out_addr.sin_port = htons(self->port+1);
inet_pton(AF_INET, "127.0.0.1", &(out_addr.sin_addr));
if (bind(fd, (struct sockaddr *)&out_addr, sizeof out_addr)) {
perror("Binding failed");
close(fd);
server_delete(self);
return NULL;
}
/* Connect the socket to our parsed address */
host = gethostbyname(self->host);
if (!host) {
fprintf(stderr, "Unknown host '%s'\n", self->host);
close(fd);
server_delete(self);
return NULL;
}
memset(&in_addr, 0, sizeof(in_addr));
in_addr.sin_family = AF_INET;
memcpy(&in_addr.sin_addr.s_addr, host->h_addr_list[0], sizeof(in_addr.sin_addr.s_addr));
in_addr.sin_port = htons(self->port);
if (connect(fd, (struct sockaddr*) &in_addr, sizeof(in_addr))) {
perror("Connecting to inputpipe-server");
close(fd);
server_delete(self);
return NULL;
}
答案 0 :(得分:1)
尝试以下操作,这可能会有所帮助
fd = socket(AF_INET, SOCK_STREAM, 0);
// Local
memset(&sa_loc, 0, sizeof(struct sockaddr_in));
sa_loc.sin_family = AF_INET;
sa_loc.sin_port = htons(LOCAL_RANDOM_PORT); /// PUT the port here which you want to open
sa_loc.sin_addr.s_addr = inet_addr(LOCAL_IP_ADDRESS);
ret = bind(fd, (struct sockaddr *)&sa_loc, sizeof(struct sockaddr));
assert(ret != -1);
// Remote
memset(&sa_dst, 0, sizeof(struct sockaddr_in));
sa_dst.sin_family = AF_INET;
sa_dst.sin_port = htons(80);
sa_dst.sin_addr.s_addr = inet_addr("64.233.163.104"); // google :)
ret = connect(fd, (struct sockaddr *)&sa_dst, sizeof(struct sockaddr));
assert(ret != -1);
答案 1 :(得分:1)
我仍然不理解您需要修复源端口的原因,但无论如何......
您感到困惑bind(2)
和listen(2)
。这是与listen(2)
互斥的connect(2)
系统调用。 bind(2)
只修复“本地名称”,即套接字的源端口号。
啊,代码......
您绑定到127.0.0.1
- 您无法从此处连接到任何非本地连接,因此错误。请改用INADDR_ANY
或您真实的可路由地址。