1,getsockopt連續調用問題
通常情況下,在一個socket fd上出現錯誤時,我們會通過
int status; socklen_t slen; getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *) &status, &slen);
這種方法來獲取具體的錯誤原因。
如果fd上出現了錯誤,那么第一次調用getsockopt會通過status返回錯誤原因。如果此時並沒有調用close(fd),按理說這個錯誤在fd上依然存在,但是如果再次調用上面的getsockopt,則會告知用戶此fd上沒有任何錯誤。。。這種情況經常會發生在函數之間傳遞fd時,一個函數A里面做了getsockopt判斷,之后將fd傳至別的函數B,函數B不知道fd的狀態,再次調用getsockopt,會誤認為fd上沒有錯誤了。
所以如果在fd上沒有任何讀寫操作的話,fd上的getsockopt要只調用一次,之后,要將該次getsockopt的狀態和fd一起傳遞給別的函數。免得出現上面的問題。
2,accept的參數問題
通常情況下,一個socket fd上等待請求,會像下面這樣做:
int clifd, clilen; sockaddr_in cliaddr; clifd = accept(listen_fd, (struct sockaddr*) &cliaddr, &clilen);
這樣是一個成功的accept調用,但是在accept返回后,你無法通過cliaddr拿到對端的IP信息。你會發現你用inet_ntop(AF_INET, &cliaddr, ip_buf, sizeof(ip_buf))得到的竟然是一個亂七八糟的對端IP地址。
正確的做法是這樣:
sockaddr_in cliaddr; int clifd, clilen = sizeof(cliaddr); clifd = accept(listen_fd, (struct sockaddr*) &cliaddr, &clilen);
看出差別了嗎?