2014-11-24 107 views
1

處理套接字的我在這種編程的新,十分感謝不打我一邊問愚蠢的問題;-)使用信號燈在C

我有下面的代碼:

SOCKET sock = open_socket(szListenHost, iListenPort); 

if (sock > 0) { 
    SOCKET client; 
    struct sockaddr_in peeraddr; 
    T_socklen len = sizeof (struct sockaddr_in); 

    char buf[1024]; 

    sin.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; 
    sin.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 
    sin.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); 
    sin.hStdError = GetStdHandle(STD_ERROR_HANDLE); 
    sin.wShowWindow = SW_HIDE; 
    dwCreationFlags = CREATE_NO_WINDOW; 

    CreateProcess(NULL, buf, NULL, NULL, FALSE, dwCreationFlags, NULL, NULL, &sin, &pin); 

    memset(&peeraddr, 0, sizeof (struct sockaddr_in)); 
    client = accept(sock, (sockaddr*)&peeraddr, &len); 

    if (client > 0) { 
     rv = message_loop(client); 
    } 
    closesocket(sock); 
} 

正如你所看到的,這是爲了詢問原因打開一個TCP套接字。

情況如下:我的客戶端應用程序(誰打開這些套接字)可能需要同時打開不同的TCP套接字,這可能會導致問題。

爲了避免這些問題,我想問問套接字是否已經打開。如果是,則等到套接字再次釋放,然後再次嘗試打開套接字。

我已經理解信號量可以用於這個意圖,但我不知道如何做到這一點。

任何人都可以幫助我嗎? 謝謝

首先我要感謝John Bollinger的快速回復。不幸的是,他們似乎是誤解:我不是在尋找一種方法來同時打開一個套接字,但我正在尋找一種當套接字可用時要注意的方法。其實,我想做到以下幾點:相反的:

SOCKET sock = open_socket(szListenHost, iListenPort);

我能做到這一點(非常基本):

while (open_socket(szListenHost, iListenPort)) {sleep (1 second;)}

然而,這意味着我需要查詢插座不斷,創造了一些開銷。我聽說信號燈可以解決這個問題,是這樣的:

SOCKET sock = handle_semaphore(open_socket(szListenHost, iListenPort));

和「handle_semaphore」將被自動等待被釋放插槽的系統,讓馬上我的客戶端程序可以打開插座,沒有被推到後面的風險。正如你所看到的,這完全是關於謠言,但我不知道如何實現這一點。有人知道是否可以使用信號量來達到這個目的,如果可能的話,給我一些關於如何做到這一點的指導?

感謝

回答

1

一旦打開,一個套接字無法重新打開,即使是關閉的。不過,您可以創建一個類似的新套接字。無論哪種方式,很難可靠地確定先前打開的套接字是否已關閉,除非關閉它。

在任何情況下,通常的範例都不需要你所要求的那種協調機制。通常,一個進程的一個線程將打開套接字並負責接受它上的連接。如果希望程序能夠一次處理多個連接,那麼每次該線程接受一個新的連接時,它將該連接分配給另一個線程或進程處理 - 通常但不一定是新創建的。

通常不需要或不希望打開一個新的套接字來接收相同地址和端口上的其他連接。通常您只需使用相同的套接字,而不必關心通過該套接字建立的任何連接的狀態。也許你可以使用信號量來協調同一進程的多個線程從同一個套接字接收連接,但是如果我是你,我會避免這種情況。

0

與此同時,情況發生了變化,我現在已經能夠將信號添加到與套接字相關的應用程序中。通常這種方式有效,但有時應用程序掛起。

一些調試後,我已經認識到了應用程序掛起的那一刻我推出以下C命令:

printf("Will it be accepted?\n");

fflush(stdout);

memset(&peeraddr, 0, sizeof (struct sockaddr_in));

client = accept(sock, (sockaddr*)&peeraddr, &len);

printf("It is accepted, the client is %d.\n",client);

=>我可以在我的調試日誌中看到「它會被接受嗎?」,但我沒有看到「它被接受,...」。我承認我在測試時很暴力(有時候我會停止調試會話而沒有讓應用程序關閉套接字......),但是您可以想象客戶的行爲方式與應用程序需要相同足夠強大。

有沒有人知道我可以如何避免「接受」命令進入這樣一個無限循環?

謝謝