![](/img/trans.png)
[英]C Socket Programming: Trying to serve new client connections using fork()
[英]Trying to fork() after new client connection to server [Socket Programming C]
所以我有一個服務器,它應該為每個與服務器的新連接創建一個新進程。 因此,我將有多個客戶端連接到一台服務器。
建立連接后,服務器應為每個新客戶端返回一個隨機數 id。
問題:服務器正在為連接到服務器的所有客戶端(終端)打印相同的隨機數 id。
應該發生什么:子進程應該為新的唯一客戶端連接生成 (rand()) id。 證明每個新客戶端都連接到服務器。 我的叉子正確嗎?
while (1)
{
pid_t childpid; /* variable to store child's process id */
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if ((childpid = fork()) == -1)
{ // fork failed.
close(new_fd);
continue;
}
else if (childpid > 0)
{ // parent process
printf("\n parent process\n");
}
else if (childpid == 0)
{ // child process
printf("\n child process\n");
printf("\n random num: %d\n", rand()); -----> Testing, should be unique for each client (its not!)
/* ***Server-Client Connected*** */
client_t client = generate_client();
}
printf("server: got connection from %s\n",
inet_ntoa(their_addr.sin_addr));
}
“rand” function 使用隱藏的“狀態”來生成下一個隨機數。 由於父級從不使用 rand,因此每個分叉的子級將獲得相同的 state,並將生成相同的隨機數序列。
幾個可能的修復:
int child_id = rand() ;
if ((childpid = fork()) == -1)
{ // fork failed.
close(new_fd);
continue;
}
... Later in the child.
printf("random num: %d", child_id) ;
您應該閱讀rand
的文檔,尤其是這一部分:
srand() function 使用該參數作為后續調用 rand() 將返回的新偽隨機數序列的種子。 如果隨后使用相同的種子值調用 srand(),則應重復偽隨機數序列。 如果在調用 srand() 之前調用了 rand(),則應生成與第一次調用 srand() 時相同的序列,種子值為 1。
你要么打電話給srand
,要么不打電話。 如果您不調用srand
,則與調用srand(1)
相同。 所以這兩種情況的邏輯是一樣的。
如果兩個進程生成不同的數字,那么就會違反rand
的要求。 正如文檔所說,“如果使用相同的種子值調用 srand(),則應重復偽隨機數序列。” 您的兩個進程都稱為srand
,具有相同的值(可能是隱式 1),因此它們都必須產生相同的序列。
我強烈建議您不要使用rand
或srand
。 只需使用具有您需要的語義的函數。 如果您需要兩個進程中不同的隨機數,請編寫 function 來生成它。 另一種選擇是在fork
之后執行類似srand(getpid() ^ (time(NULL)<<8))
的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.