tcp協議是面向流的,read和write呼叫的返回值往往小於引數指定的位元組數。對於read呼叫,如果接收緩衝區中有20位元組,請求讀100個位元組,就會返回20。對於write呼叫,如果請求寫100個位元組,而傳送緩衝區中只有20個位元組的空閒位置,那麼write會阻塞,直到把100個位元組全部交給傳送緩衝區才返回(socket阻塞時,write一直阻塞直到所有資料都交給緩衝區)。但如果socket檔案描述符中有o_nonblock標誌,則write不阻塞,直接返回20。
為避免這些情況干擾主程式邏輯,確保讀寫所請求的位元組數,應包裝read和write函式。
當設定socket為非阻塞模式時,要用select()或epoll()判斷什麼時候可正常寫入或讀出。
sszie_t write(int fd, const void *buf, size_t count);
return:成功,返回寫入的位元組數;失敗-1。
在網路程式中,當我們向socket寫時有兩種可能:
write的返回值大於0,表示寫了部分或者全部的資料。
返回值小於0,此時出現了錯誤。我們要根據錯誤型別來處理。如果錯誤為eintr表示在寫的時候出現了中斷錯誤,應重試。如果為epipe表示網路連線出現了問題(對方已經關閉了連線,返回-1)(注:epipe時,需要設定sigpipe訊號處理,當採用預設的sigpipe訊號處理時程式直接退出,write不會返回-1)。
此外還有可能socket為非阻塞(o_nonblock),當緩衝區滿時,立即返回0。(我的想法) ----錯誤想法,fd設定為非阻塞時,不能寫立即返回-1,設定errno為eagain或ewouldblock(man write errors)。
返回0時,表示未寫資料,繼續寫即可。
tcp是全雙工的通道,可以看作兩條單工通道,tcp連線的兩個端點各負責一條。當對端呼叫close,雖然本意是關閉整個兩條通道,但本端只是收到fin包。按照tcp協議的語義,表示對端只是關閉了其所負責的那一條單工通道,仍然可以繼續接收資料。也就是說,因為tcp協議的限制,乙個端點無法獲知對端的socket是呼叫了close還是shutdown。
但第一次對其呼叫write方法時,如果 a 傳送資料到 b 的快取沒問題,會返回正確寫入,但 a 傳送的報文會導致b傳送rst報文,因為 b 的socket已經呼叫了close,完全關閉,既不傳送,也不接收資料。所以 a 第二次呼叫write方法(假設在收到 rst 報文之後),會生成 sigpipe 訊號,導致程序退出。
int my_write(int fd, void *buffer, intlen)
bytes_left -=writen_bytes;
ptr +=written_bytes;
}return
len;
}
ssize_t read(int fd, void *buf, size_t count);
return:成功,返回讀取到的位元組數;失敗-1。
返回值為0,表示已經讀到檔案的結束;返回值小於0 表示出現了錯誤。如果錯誤為eintr說明讀是由中斷引起的(繼續讀),如果是econnrest表示網路連線出了問題。
read()阻塞時,一直等,等於0表示檔案結束或網路連線關閉;read()非阻塞,無資料可讀時立即返回-1,errno為eagain(若一直讀,一直返回-1,errno為eagain),連線關閉時返回0。
int my_read(int fd,void *buffer,intlength)
else
if(bytes_read==0) //
對方close連線(收到fin包)
break
; bytes_left-=bytes_read;
ptr+=bytes_read;
}
return(length-bytes_left);
}
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr * from, int *fromlen);
int sendto(int sockfd, const void *msg, int len, unsigned int flags, struct sockaddr *to, int tolen);
注:如果對資訊的**不感興趣,可以將from和fromlen設定為null。
Socket收發資料
client write server client read 位元組數writebyte unsignedbyte readunsignedbyte 1 writelengthstring string readstring writebyte byte readbyte 1 writeunsig...
socket資料收發
socket讀寫 tcp協議是面向流的,read和write呼叫的返回值往往小於引數指定的位元組數。對於read呼叫,如果接收緩衝區中有20位元組,請求讀100個位元組,就會返回20。對於write呼叫,如果請求寫100個位元組,而傳送緩衝區中只有20個位元組的空閒位置,那麼write會阻塞,直到把...
socket 指定網口收發資料
在系統中,可能會有多片網口,工作在不同的網段,同時有不同的閘道器,socket需要繫結其中的乙個網絡卡,進行網路的通訊。設定socket指定為eth1進行收發網路包 define inte xename eth1 struct ifreq inte ce strncpy inte ce.ifr if...