我是一個新手在C中進行遊戲,我的小項目是編寫一個簡單的SOCKS4代理。感謝這裏的幫助,我到目前爲止使用了非阻塞套接字和poll()作爲我的例程。然而,在這一點上,我似乎有2個問題:代理中的非阻塞套接字和輪詢()怪癖 - 新手
傳出插槽dstSocket如果輸入插座rcvSocket被關閉,反之亦然不會被關閉。我不檢查這個循環,但我不知道如何。我嘗試POLLHUP作爲啓示,但似乎並沒有這樣做。普通的檢查似乎是recv()是否返回0,但是它對非阻塞套接字是否也有效?如果是這樣,那麼如何才能與revents一起工作,我似乎無法弄清楚我會把它放在哪裏,因爲如果POLLIN | POLLPRI被設置在我看來recv()永遠不應該返回0?另外我不明白POLLIN和POLLPRI之間的確切區別是什麼,在這兩種情況下,在我看來只是一個檢查「數據可供閱讀」?
代理似乎適用於我使用netcat測試的連接。但是,如果我使用瀏覽器,它說(當我的目標網站)是否我想保存「二進制數據」。我在wireshark中檢查了數據,從服務器收到的數據看起來正確地按字節轉發到客戶端。如果有人也許有一個想法,爲什麼,可能與這一計劃發生這將是很好:)
附相關的代碼(注意編程新手):
fds[1].fd = dstSocket;
fds[0].fd = rcvSocket;
fds[1].events = POLLIN | POLLPRI | POLLHUP;
fds[0].events = POLLIN | POLLPRI | POLLHUP;
timer = poll(fds, 2, timeout_msecs); /* i dont use this yet */
fcntl(rcvSocket, F_SETFL, O_NONBLOCK);
fcntl(dstSocket, F_SETFL, O_NONBLOCK);
while (1 == 1)
{
if (fds[0].revents & POLLIN | POLLPRI)
{
recvMsgSize = recv(rcvSocket, rcvBuffer, RCVBUFSIZE, 0);
if (recvMsgSize > 0) {send(dstSocket, rcvBuffer, recvMsgSize, 0);}
}
if (fds[1].revents & POLLIN | POLLPRI)
{
sndMsgSize = recv(dstSocket, sndBuffer, RCVBUFSIZE, 0);
if (sndMsgSize > 0) { send(rcvSocket, sndBuffer, sndMsgSize, 0);}
}
if ((fds[0].revents & POLLHUP) || (fds[1].revents & POLLHUP))
{
close(rcvSocket);
close(dstSocket);
}
}
雖然這裏可能不是真正的問題,但最終還是需要處理:使用非阻塞套接字send()可能不會發送請求它發送的所有字節。另外,您是否配置瀏覽器將您的程序用作SOCKS代理?如果是這樣,您需要實現SOCKS協議以使瀏覽器正常工作。 – nos
2.注意。注意|和&運營商運營商優先'fds [1] .revents&POLLIN | POLLPRI'與'(fds [1] .revents&POLLIN)|相同POLLPRI',你需要'fds [1] .revents&(POLLIN | POLLPRI)'(或者按照caf – nos
的建議放棄POLLPRI顯然是一個firefox錯誤,chrome和其他襪子應用程序工作。 t知道這一點,謝謝。 – user912877