測試unix數據報套接字時,一個程序收,一個程序發,分別綁定自己的socket。結果在收的部分,返回的發送方的地址總是空的,但是返回的地址長度又是對的。
while ( 1 ) { bzero(&clientaddr, sizeof(struct sockaddr_un)); slen = 0; rn = recvfrom(fd,buf, sizeof(buf), 0 ,(struct sockaddr *)&clientaddr, slen); if ( rn == -1) { perror("recvfrom"); } buf[n] = 0; }
仔細對比unp的代碼,發現 slen = 0 這行改成 slen = sizeof(strcut sockaddr_un) 結果就對了,細看man
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
=====================================================================================================================
If src_addr is not NULL, and the underlying protocol provides the source address, this source address is filled in. When src_addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL. The argument addrlen is a value-result argument, which the caller should initialize before the call to the size of the buffer associated with src_addr, and modified on return to indicate the actual size of the source address. The returned address is truncated if the buffer provided is too small; in this case, addrlen will return a value greater than was supplied to the call.
紅色部分指出,最后一個參數addrlen是一個"值-結果"的參數,賦給它的初始值用來指定拷貝到倒數第二個參數 src_addr 里面的字節數,返回實際值是實際的源地址結構的大小。當傳入的參數小於輸出的值,說明返回的源地址被截斷了。
上面的例子中,傳入的值為0,而輸出的值大於0,明顯這里有問題,未拷貝任何數據到返回的源地址clientaddr。