linux 中的奇妙錯誤(持續(xù)更新)

linux 中的奇妙錯誤

1/無名管道

當(dāng)打開一個管道之后巩踏,將管道的讀端關(guān)閉音榜,然后在向其中寫入內(nèi)容稚叹,進程會被信號SIGPIPE殺死动雹,基本無調(diào)試信息輸出债朵。


int main(int argc, char const *argv[])
{

    int fd[2];

    int ret=pipe(fd);
    //關(guān)閉讀端
    close(fd[0]);
    // 向管道中寫入東西
    write(fd[1],"string",strlen("string"));
    // 這里進程會收到 13:SIGPIPE 進程會被殺死
    printf("這里不會輸出\n");
    return 0;
}

2/有名管道

有名管道凫海,如果使用open函數(shù)以只讀的方式打開的時候其會阻塞馆类,等待另一個進程以寫的方式打開這個管道的時候亩码,程序才會繼續(xù)執(zhí)行。


下面兩個程序 雖然代碼結(jié)構(gòu)上看起來很整齊茸塞,可以打開兩個半雙工的管道躲庄,構(gòu)成一個全雙工的通信,但由于 其都是先進行只讀打開導(dǎo)致兩個程序都阻塞在open函數(shù)這里無法繼續(xù)钾虐。

int fd_read=open(fifo1,O_RDONLY);
// 程序會阻塞在這里噪窘,不會繼續(xù)執(zhí)行下去
int fd_write=open(fifo2,O_WRONLY);


int fd_read=open(fifo2,O_RDONLY);
// 程序會阻塞在這里,不會繼續(xù)執(zhí)行下去
int fd_write=open(fifo1,O_WRONLY);

3/向一個關(guān)閉的描述符寫東西

如果向一個關(guān)閉的描述符寫東西效扫,進程會被信號殺死

例如管道 網(wǎng)絡(luò)描述符倔监,所以一般都是寫端主動關(guān)閉,讀端口被動關(guān)閉菌仁。

4/網(wǎng)絡(luò)編程中結(jié)構(gòu)體sockaddr_in結(jié)構(gòu)體的填充

mac 手冊中inet(4) 結(jié)構(gòu)體是這么填充的

           struct sockaddr_in {
                   short   sin_family;
                   u_short sin_port;
                   struct  in_addr sin_addr;
                   char    sin_zero[8];
           };

但POSIX定義確實

           struct sockaddr_in {
                  uint8_t        sin_len;
                   sa_family_t    sin_family;
                   i_port_t        sin_port;
                   struct in_addr sin_addr;
                   char           sin_zero[8];
           };

這意味著如果在定義 sockaddr_in 變量的時候使用 下面這種初始化方式

struct sockaddr_in s{sin_family, sin_port, sin_addr};

則運行可能會出現(xiàn)錯誤浩习!

由于結(jié)構(gòu)體中成都是 _t類型(即 int,long,int,short,long long) 在一定情況下 就算填充位置錯誤,但由于類型匹配济丘,編譯器可能不會發(fā)出警告谱秽,而且由于這樣使用大多數(shù)情況下都是正確的(即便是POSIX標準,但好像linux并沒有遵守)摹迷,但如果發(fā)生錯誤弯院,一般很難發(fā)現(xiàn).

所以應(yīng)該這么定義

struct sockaddr_in s;
s->sin_family = sin_family;
s->sin_port = sin_port;
s->sin_addr = sin_addr;

5/linux 網(wǎng)絡(luò)編程 write read recv send

轉(zhuǎn)載

建立好了TCP連接之后,我們就可以把得到的套接字當(dāng)做文件描述符來使用泪掀,由此,想到了網(wǎng)絡(luò)程序里面的基本的讀寫函數(shù)read和write函數(shù)颂碘。
Write函數(shù)
Ssize_t write(int fd,const void *buf,size_t nbytes);

Write函數(shù)將buf中的nbytes字節(jié)內(nèi)容寫入到文件描述符中异赫,成功返回寫的字節(jié)數(shù)椅挣,失敗返回-1.并設(shè)置errno變量。在網(wǎng)絡(luò)程序中塔拳,當(dāng)我們向套接字文件描述舒服寫數(shù)據(jù)時有兩種可能:
1鼠证、write的返回值大于0,表示寫了部分數(shù)據(jù)或者是全部的數(shù)據(jù)靠抑,這樣用一個while循環(huán)不斷的寫入數(shù)據(jù)量九,但是循環(huán)過程中的buf參數(shù)和nbytes參數(shù)是我們自己來更新的,也就是說颂碧,網(wǎng)絡(luò)編程中寫函數(shù)是不負責(zé)將全部數(shù)據(jù)寫完之后再返回的荠列,說不定中途就返回了!
2载城、返回值小于0肌似,此時出錯了,需要根據(jù)錯誤類型進行相應(yīng)的處理诉瓦。
如果錯誤是EINTR表示在寫的時候出現(xiàn)了中斷錯誤川队,如果是EPIPE表示網(wǎng)絡(luò)連接出現(xiàn)了問題。

Read函數(shù)
Ssize_t read(int fd,void *buf,size_t nbyte)

Read函數(shù)是負責(zé)從fd中讀取內(nèi)容睬澡,當(dāng)讀取成功時固额,read返回實際讀取到的字節(jié)數(shù),如果返回值是0煞聪,表示已經(jīng)讀取到文件的結(jié)束了斗躏,小于0表示是讀取錯誤。
如果錯誤是EINTR表示在寫的時候出現(xiàn)了中斷錯誤米绕,如果是EPIPE表示網(wǎng)絡(luò)連接出現(xiàn)了問題瑟捣。

有了上面的兩個函數(shù),我們就可以向客戶端或者是服務(wù)器端進行數(shù)據(jù)傳輸了栅干!比如我要傳送一個結(jié)構(gòu)體迈套,可以使用下面的方法
客戶端向服務(wù)器:

Struct student stu;  
Write(sock,(void *)&stu,sizeof(struct student));  

服務(wù)器讀:

Char buffer[sizeof(struct student)];  
Struct *my_student;  
Read(sock,(void *)buffer,sizeof(struct student));  
My_student=(struct student)buffer;  

在網(wǎng)絡(luò)上傳遞數(shù)據(jù)時,我們一般把數(shù)據(jù)轉(zhuǎn)換為char類型碱鳞,接收的時候也是一樣的的桑李。沒必要在網(wǎng)絡(luò)上傳遞指針。
Recv函數(shù)和send函數(shù)
Recv函數(shù)和read函數(shù)提供了read和write函數(shù)一樣的功能窿给,不同的是他們提供了四個參數(shù)贵白。


Int recv(int fd,void *buf,int len,int flags)
Int send(int fd,void *buf,int len,int flags)

前面的三個參數(shù)和read、write函數(shù)是一樣的崩泡。第四個參數(shù)可以是0或者是一下組合:
MSG_DONTROUTE:不查找表
是send函數(shù)使用的標志禁荒,這個標志告訴IP,目的主機在本地網(wǎng)絡(luò)上角撞,沒有必要查找表呛伴,這個標志一般用在網(wǎng)絡(luò)診斷和路由程序里面勃痴。
MSG_OOB:接受或者發(fā)生帶外數(shù)據(jù)
表示可以接收和發(fā)送帶外數(shù)據(jù)。
MSG_PEEK:查看數(shù)據(jù)热康,并不從系統(tǒng)緩沖區(qū)移走數(shù)據(jù)
是recv函數(shù)使用的標志沛申,表示只是從系統(tǒng)緩沖區(qū)中讀取內(nèi)容,而不清楚系統(tǒng)緩沖區(qū)的內(nèi)容姐军。這樣在下次讀取的時候铁材,依然是一樣的內(nèi)容,一般在有過個進程讀寫數(shù)據(jù)的時候使用這個標志奕锌。
MSG_WAITALL:等待所有數(shù)據(jù)
是recv函數(shù)的使用標志著觉,表示等到所有的信息到達時才返回,使用這個標志的時候歇攻,recv返回一直阻塞固惯,直到指定的條件滿足時,或者是發(fā)生了錯誤缴守。

6/信號缺陷

sinal 信號有一的機制是 通過某個信號的標志位來判斷葬毫,信號是否發(fā)生所以當(dāng)多個相同信號同時發(fā)生的時候,信號處理函數(shù)可能調(diào)用的次數(shù)會比預(yù)想的次數(shù)要少很多

同時信號中盡量不要使用公共資源屡穗,和線程一樣贴捡,信號的處理函數(shù)同樣會對其他程序的運行造成影響,例如如果在signal_handle中使用printf村砂,可能在主程序中printf運行一半的時候烂斋,被中斷,那么結(jié)果可能會輸出意料之外的數(shù)據(jù)础废。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汛骂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子评腺,更是在濱河造成了極大的恐慌帘瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒿讥,死亡現(xiàn)場離奇詭異蝶念,居然都是意外死亡,警方通過查閱死者的電腦和手機芋绸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門媒殉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摔敛,你說我怎么就攤上這事廷蓉。” “怎么了马昙?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵苦酱,是天一觀的道長售貌。 經(jīng)常有香客問我,道長疫萤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任敢伸,我火速辦了婚禮扯饶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘池颈。我一直安慰自己尾序,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布躯砰。 她就那樣靜靜地躺著每币,像睡著了一般。 火紅的嫁衣襯著肌膚如雪琢歇。 梳的紋絲不亂的頭發(fā)上兰怠,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音李茫,去河邊找鬼揭保。 笑死,一個胖子當(dāng)著我的面吹牛魄宏,可吹牛的內(nèi)容都是我干的秸侣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宠互,長吁一口氣:“原來是場噩夢啊……” “哼味榛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起予跌,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤搏色,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后匕得,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體继榆,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年汁掠,在試婚紗的時候發(fā)現(xiàn)自己被綠了略吨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡考阱,死狀恐怖翠忠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乞榨,我是刑警寧澤秽之,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布当娱,位于F島的核電站,受9級特大地震影響考榨,放射性物質(zhì)發(fā)生泄漏跨细。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一河质、第九天 我趴在偏房一處隱蔽的房頂上張望冀惭。 院中可真熱鬧,春花似錦掀鹅、人聲如沸散休。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戚丸。三九已至,卻和暖如春扔嵌,著一層夾襖步出監(jiān)牢的瞬間限府,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工对人, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谣殊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓牺弄,卻偏偏與公主長得像姻几,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子势告,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx蛇捌?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 32,679評論 24 1,002
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法咱台,類相關(guān)的語法络拌,內(nèi)部類的語法,繼承相關(guān)的語法回溺,異常的語法春贸,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • socket通信原理 socket又被叫做套接字,它就像連接到兩端的插座孔一樣,通過建立管道,將兩個不同的進程之間...
    jiodg45閱讀 1,140評論 0 1
  • socket編程中write允粤、read和send、recv之間的區(qū)別 -軌跡16-ChinaUnix博客 一旦,我...
    boboxxd閱讀 1,562評論 0 0
  • 一世人一世情类垫!有人說情是仇恨司光,是罪惡的開始。也有人說情是蜜糖悉患,是甜蜜的根源残家。 我只是一個普通人,一個普通的家庭...
    流浪的幸福閱讀 114評論 0 0