作爲一個學校項目,我必須重新編碼一個IRC服務器,但我堅持一個問題。 我想要做的是接收並執行客戶端的命令而不會阻塞(因爲我有很多客戶端需要服務)。C socket:非阻塞方式讀取 n分離的命令
編輯:使用非阻塞套接字和叉()是被禁止的這個項目
關於命令:
- 他們是 「\ r \ n」 分隔
- 他們是512字符最大值
我的第一次嘗試是使用getline循環。它的工作完美,但只針對一個客戶端(如函數getline塊時,他們被提更多的閱讀,而不是傳遞給下一個客戶端)
bool recv_cmd(t_hdl *hdl)
{
char *raw;
size_t len;
FILE *input_stream;
ssize_t nread;
len = 0;
raw = NULL;
if ((input_stream = fdopen(dup(hdl->sender->fd), "r")) == NULL)
return (false);
while ((nread = getline(&raw, &len, input_stream)) > 0)
{
printf("%lu\n", nread);
parse_cmd(hdl, raw);
exec_cmd(hdl);
}
fclose(input_stream);
return (true);
}
如果我刪除從像這樣的循環,則對getline,這對所有的工作客戶端,但只執行來自客戶端的第一個命令(例如,如果客戶端發送「命令1 \ r \ ncommand2 \ r \ n」個,僅執行命令1)
bool recv_cmd(t_hdl *hdl)
{
char *raw;
size_t len;
FILE *input_stream;
len = 0;
raw = NULL;
if ((input_stream = fdopen(dup(hdl->sender->fd), "r")) == NULL)
return (false);
if (getline(&raw, &len, input_stream) != -1)
{
parse_cmd(hdl, raw);
exec_cmd(hdl);
//free(raw
}
fclose(input_stream);
return (true);
}
我還試圖刪除FCLOSE (),所以當我們讀取command1時,command2停留在流緩衝區中,但它也不起作用。
該項目的主題還表示「使用循環緩衝區,以保護和優化正在發送和接收的各種命令和響應」「。
我應該怎麼做?在這種情況下使用循環緩衝區比我的getline有什麼優勢?
如何使用*非阻塞*套接字和使用例如輪詢'select'? –
您的客戶機/服務器I/O **是否在低級讀寫操作(即:對您的項目的要求)中具有非阻塞性,或者您是否必須能夠處理多個併發客戶機以快速,無序的方式從服務器連接? – DevNull
@Someprogrammerdude我已經在使用select但是非阻塞套接字不允許用於這個項目:/ –