2013-09-23 29 views
0

我正在使用C,Linux和GIO GSocket構建一個小型應用程序,以通過TCP與數字投影儀進行通信。套接字連接成功,我可以將消息成功發送到投影機。我的問題是,我無法接收投影機在收到命令時返回的自動確認消息。當我發送一條消息,然後使用g_socket_receive,它會阻止並且從未收到響應。如何通過與GSocket的TCP連接發送消息時控制出站端口?

基於其他語言的過去類似問題,我懷疑問題是,當我使用g_socket_send發送消息時,消息在隨機可用的本地端口上發送。投影機然後自動回覆信息來源的端口。不知道它使用了哪個端口,我無法讓我的GSocket在正確的端口上偵聽。在其他語言中,手動設置本地出站​​端口是一件簡單的事情,所以我知道響應會回到哪裏。然而,我一直無法找到任何有關如何使用GSocket的信息。

任何人都可以提供這方面的任何幫助,或任何想法,我可能缺少什麼問題?

謝謝!

+0

如果您發起TCP連接到服務器(投影機),在TCP/IP堆棧管理本地端口(你只需要知道服務器的IP :PORT pair),所以你不需要「聽」任何東西;聽是爲了自己創建一個服務器。我的猜測是,你的問題在別的地方...... – Unknown

回答

0

您的讀取/接收電話很有可能是因爲您要讀取/接收的字節數超過發送的答案的長度。

出於測試目的,做這樣的事情:

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

0

您可以使用g_socket_bind函數將出站GSocket綁定到本地地址(IP和端口),就像您在偵聽套接字時所做的一樣。

雖然這樣做不太可能解決您的問題。投影機應將回複數據包發送到發送請求的端口;很少需要將客戶端套接字綁定到特定的端口。驗證wiresharktcpdump發送和接收的內容。

+0

因此,如果我沒有將我的套接字綁定到特定的本地端口,當我使用與我剛纔調用g_socket_send()相同的套接字調用g_socket_receive()時,它應該自動檢查輸入的數據是否與發送消息的端口號相同?如果是這種情況,那麼我的問題必須在其他地方。我會嘗試wireshark,看看我能看到什麼。 – DrRocket