我現在忙了2天,仍然不明白。這段代碼做了什么select()?
我知道如果有一個可以接受的傳入連接,copy.fd_array[]它將包含ListenSocket但當 while 回圈重復時它仍然存在。那么我們如何知道客戶端是否斷開連接呢?fd_set copy通話后包含什么select()?
fd_set master;
FD_ZERO(&master);
FD_SET(ListenSocket, &master);
while (1)
{
fd_set copy = master;
select(FD_SETSIZE, ©, NULL, NULL, NULL);
for (int i = 0; i < FD_SETSIZE; i )
{
// If new connection
if (FD_ISSET(ListenSocket, ©))
{
printf("[ ] New connection\n");
// Accept connection
SOCKET AcceptedClient = accept(ListenSocket, NULL, NULL);
FD_SET(AcceptedClient, &master);
// Send welcome message to client
char buff[128] = "Hello Client!";
send(AcceptedClient, buff, sizeof(buff), 0);
}
}
}
uj5u.com熱心網友回復:
我現在忙了2天,仍然不明白。
難怪你看不懂代碼:示例中的代碼是胡說八道。
檢查ListenSocket應該在for回圈外完成。并且FD_ISSET還必須檢查使用接受的連接accept。
回圈內的正確代碼while如下所示:
fd_set copy = master;
select(FD_SETSIZE, ©, NULL, NULL, NULL);
// If new connection
if (FD_ISSET(ListenSocket, ©))
{
...
}
for (int i = 0; i < FD_SETSIZE; i )
{
// If an existing connection has data
// or the connection has been closed
if ((i != ListenSocket) && FD_ISSET(i, ©))
{
nBytes = recv(i, buffer, maxBytes, 0);
// Connection dropped
if(nBytes < 1)
{
close(i); // other OSs (Linux, MacOS ...)
// closesocket(i); // Windows
FD_CLR(i, &master);
}
// Data received
else
{
...
}
}
}
我知道如果有一個可以接受的傳入連接,
copy.fd_array[]它將包含ListenSocket但當while回圈重復時它仍然存在。
在 select() 呼叫之后 fd_set 副本包含什么?
首先:在呼叫之前select(),copy.fd_array[]必須包含您感興趣的所有套接字句柄。這意味著它必須包含ListenSocket所有由回傳的句柄accept()。
master.fd_array[]包含所有這些句柄,因此fd_set copy = master;將確保copy.fd_array[]也包含所有這些句柄。
select()(NULL作為最后一個引數)將等到至少一個套接字變為“可用”。這意味著它將等待至少以下條件之一為真:
- 接受的連接被
accept()對方關閉 - 使用接受的連接
accept()具有可以接收的資料 - 有一個可以使用的新連接
accept(ListenSocket...)
As soon as one condition is fulfilled, select() removes all other handles from copy.fd_array[]:
ListenSocketis removed fromcopy.fd_array[]if there is no incoming connection- A handle returned by
accept()is removed from that array if the connection has neither been closed nor new data is available
If two events happen the same time, copy.fd_array[] will contain more than one handle.
You use FD_ISSET() to check if some handle is still in the array.
So how do we know if a client is disconnected?
When you detect FD_ISSET(i, ©) for a value i that has been returned by accept(), you must call recv() (under Linux read() would also work):
If recv() returns 0 (or negative in the case of errors), the other computer has dropped the connection. You must call close() (closesocket() on Windows) and remove the handle from copy.fd_array[] (this means: you must remove it from master.fd_array[] because of the line fd_set copy = master;).
If recv() returns a positive value, this is the number of bytes that have been received.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/426701.html
上一篇:Python套接字掛起連接/接受
下一篇:UDP服務器并發測驗
