如何通过与GSocket的TCP连接发送消息时控制出站端口?

问题描述:

我正在使用C,Linux和GIO GSocket构建一个小型应用程序,以通过TCP与数字投影仪进行通信。套接字连接成功,我可以将消息成功发送到投影机。我的问题是,我无法接收投影机在收到命令时返回的自动确认消息。当我发送一条消息,然后使用g_socket_receive,它会阻止并且从未收到响应。如何通过与GSocket的TCP连接发送消息时控制出站端口?

基于其他语言的过去类似问题,我怀疑问题是,当我使用g_socket_send发送消息时,消息在随机可用的本地端口上发送。投影机然后自动回复信息来源的端口。不知道它使用了哪个端口,我无法让我的GSocket在正确的端口上侦听。在其他语言中,手动设置本地出站​​端口是一件简单的事情,所以我知道响应会回到哪里。然而,我一直无法找到任何有关如何使用GSocket的信息。

任何人都可以提供这方面的任何帮助,或任何想法,我可能缺少什么问题?

谢谢!

+0

如果您发起TCP连接到服务器(投影机),在TCP/IP堆栈管理本地端口(你只需要知道服务器的IP :PORT pair),所以你不需要“听”任何东西;听是为了自己创建一个服务器。我的猜测是,你的问题在别的地方...... – Unknown

您的读取/接收电话很有可能是因为您要读取/接收的字节数超过发送的答案的长度。

出于测试目的,做这样的事情:

int fd = -1; 
/* setup fd */ 
char buffer[1024] = {0}; 
ssize_t size_buffer = sizeof(buffer) - 1; 
size_t size_read_total = 0; 
ssize_t size_read = 0; 

while (size_buffer > size_read_total) 
{ 
    size_read = read(fd, buffer + size_read_total, 1); /* Wait until exactly one byte had been read. */ 
    if (-1 = size_read) 
    { 
    if (EINTR == errno) 
    { 
     continue; 
    } 

    if ((EAGAIN == errno) || (EWOULDBLOCK == errno)) 
    { 
     continue; 
    } 

    break; /* Fatal error */ 
    } 
    else (0 == size_read) 
    { 
    break; /* Connection closed by sending side. */ 
    } 

    size_read_total += size_read; 
} 

if (-1 == size_read) 
{ 
    perror("read() failed"); 
} 
else 
{ 
    printf("Received %zd bytes as: '%s'\n", size_read_total, buffer); 
} 
+0

我在哪里插入这个关于g_socket_read调用?在阻塞超时后运行? – DrRocket

+0

@DrRocket:用这个代替g_socket_read_call。 – alk

您可以使用g_socket_bind函数将出站GSocket绑定到本地地址(IP和端口),就像您在侦听套接字时所做的一样。

虽然这样做不太可能解决您的问题。投影机应将回复数据包发送到发送请求的端口;很少需要将客户端套接字绑定到特定的端口。验证wiresharktcpdump发送和接收的内容。

+0

因此,如果我没有将我的套接字绑定到特定的本地端口,当我使用与我刚才调用g_socket_send()相同的套接字调用g_socket_receive()时,它应该自动检查输入的数据是否与发送消息的端口号相同?如果是这种情况,那么我的问题必须在其他地方。我会尝试wireshark,看看我能看到什么。 – DrRocket