久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Linux下簡(jiǎn)單的socket通信實(shí)例

 檸檬冰啡咖 2018-02-02

 

 If you spend too much time thinking about a thing, you’ll never get it done.

                                                                                                                                      —Bruce Lee

      學(xué)習(xí)網(wǎng)絡(luò)編程也一段時(shí)間了,剛開始看《UNIX網(wǎng)絡(luò)編程》的時(shí)候,,覺得這本厚厚的書好難?。】吹胶髞?,發(fā)現(xiàn)并沒有想象中的那么難,。如果你是新手,建議你看到第二部分結(jié)束后,,開始著手寫代碼,。不寫代碼肯定是不行的???00遍也沒有敲一遍實(shí)現(xiàn)一遍來的清楚,。敲完以后,帶著問題去看書,,你會(huì)更加有針對(duì)性,。提高的速度是飛快的,這也是學(xué)習(xí)任何一本書,、一門語言的唯一手段,。

  寫這個(gè)博客也是因?yàn)閯傞_始學(xué)的時(shí)候,查了好多別人寫的東西,,百度了以后,,發(fā)現(xiàn)大家只是把所有的代碼一貼。并沒有講解每個(gè)函數(shù)的功能,。我甚至不知道哪個(gè)函數(shù)是哪個(gè)頭文件下的,。造成我對(duì)函數(shù)很不理解。下面我會(huì)對(duì)每個(gè)函數(shù)的功能,,和它的頭文件以及函數(shù)原型寫出來,,讓大家參考,第一次寫博客,,有什么錯(cuò)誤的地方,,希望大家指正,。可以在下面給我留言,,也是我繼續(xù)寫下去的動(dòng)力,。

     我很希望和大家一起分享學(xué)習(xí)網(wǎng)絡(luò)編程遇到的種種困難與不順,也希望和大家一起討論其中遇到的問題,,一起成長(zhǎng),,如果你剛開始打算學(xué)習(xí)網(wǎng)絡(luò)編程,那這篇文章一定能給你一些幫助,。

  我的郵箱:[email protected],,轉(zhuǎn)載請(qǐng)注明出處:http://www.cnblogs.com/yusenwu/p/4579167.html。

     關(guān)于怎樣介紹這個(gè)簡(jiǎn)單的實(shí)例:(基本上涵蓋了《UNIX網(wǎng)絡(luò)編程》1-5章的內(nèi)容,,更深,,更細(xì)的,需要我們?cè)偌?xì)讀這本書

      --> 1,、代碼展示,,功能介紹

  --> 2、首先介紹一下客戶端和服務(wù)端中函數(shù)的功能以及函數(shù)的原形,。

  --> 3,、關(guān)于連接三次握手和TCP連接關(guān)閉時(shí)候的分組交換

      --> 4、IPv4,、IPv6套接字的地址結(jié)構(gòu)

  --> 5、一些好的學(xué)習(xí)網(wǎng)站總結(jié)

  --> 6,、代碼下載

  --> 7,、總結(jié)

  --> 8、實(shí)現(xiàn)一個(gè)echo的實(shí)例,,代碼可以到Github上下載

client.c

按 Ctrl+C 復(fù)制代碼
按 Ctrl+C 復(fù)制代碼

-執(zhí)行:gcc client.c -o client    后啟動(dòng) ./client 客戶端程序 啟動(dòng)前先啟動(dòng)./server-----------------------------------------

 server.c

按 Ctrl+C 復(fù)制代碼
按 Ctrl+C 復(fù)制代碼

-執(zhí)行:gcc server.c -o server    后啟動(dòng) ./server 服務(wù)端程序-------------------------------------------------------

 

      > 1,、代碼展示,功能介紹

   上面這個(gè)簡(jiǎn)單的socket通信的代碼要實(shí)現(xiàn)的功能:從客戶端發(fā)送一條消息后,,服務(wù)端接收這條消息,,并在服務(wù)端顯示(recv msg from client:****)。

   

  > 2,、首先介紹一下客戶端和服務(wù)端中函數(shù)的功能以及函數(shù)的原形,。 

#include <sys/socket.h> 
int socket(int family, int type, int protocol);   //指定期望的通信協(xié)議類型,返回的文件描述符和套接字描述符類似,,我們成為套接字描述符,,簡(jiǎn)稱sockfd  

 family:協(xié)議族

family 說明
AF_INET IPv4協(xié)議 
AF_INET6 IPv6
AF_LOCAL Unix域協(xié)議(15章)
AF_ROUTE  路由套接字(18章)
AF_KEY 密鑰套接字(19章)

 type:套接字的類型

type 說明
SOCK_STREAM(常用) 字節(jié)流套接字
SOCK_DGRAM 數(shù)據(jù)報(bào)套接字
SOCK_SEQPACKET  有序分組套接字
SOCK_RAW 原始套接字

 protocol:協(xié)議類型的常量或設(shè)置為0,以選擇給定的family和type組合的系統(tǒng)默認(rèn)值

protocol 說明
IPPROTO_TCP TCP傳輸協(xié)議
IPPROTO_UDP UDP傳輸協(xié)議
IPPROTO_SCTP SCTP傳輸協(xié)議

    

#include<arpa/inet.h>
int inet_pton(int family,const char *strptr,void *addrptr);//成功返回1,,格式不對(duì)返回0,,出錯(cuò)返回-1
//作用:p代表表達(dá)式 n代表數(shù)值 以后所寫的所有代碼中都有可能會(huì)需要這個(gè)函數(shù),,所以這個(gè)函數(shù)很重要
//將char所指向的字符串,通過addrptr指針存放
//他的反函數(shù): inet_ntop()作用相反,??梢园俣炔殚嗊@個(gè)函數(shù)的功能。因?yàn)槔永镂覀儧]有涉及到,,就不介紹了,。以后用到的時(shí)候再說
//需要注意的是:當(dāng)他發(fā)生錯(cuò)誤的時(shí)候,errno的值會(huì)被置為EAFNOSUPPORT 關(guān)于errno值我們一會(huì)兒介紹,。
#include <sys/socket.h> 
int connect(int sockfd,const struct sockaddr* servaddr,socklen_t addrlen);//用connect函數(shù)來建立與TCP服務(wù)器的連接
#include<unistd.h>
int close(int sockfd);//關(guān)閉socket,,并終止TCP連接
#include <sys/socket.h>
int bind(int sockfd,const struct* myaddr,socklen_t addrlen);//把本地協(xié)議地址賦予一個(gè)套接字。也就是將32位的IPv4或128位ipv6與16位的TCP或者UDP組合,。
#include<sys/socket.h>
int listen(int sockfd,int backlog)//成功返回0,失敗返回-1     listen函數(shù)僅由TCP服務(wù)器調(diào)用
//listen函數(shù)將會(huì)做兩件事:
//1:我們?cè)趧?chuàng)建套接字的時(shí)候使用了socket函數(shù),,它創(chuàng)建的套接字是主動(dòng)套接字,bind函數(shù)的功能就是通過這個(gè)將主動(dòng)套接字,,變成被動(dòng)套接字,告訴內(nèi)核應(yīng)該接受指向這個(gè)套接字的請(qǐng)//求,CLOSED狀態(tài)變成LISTEN狀態(tài)
//2:本函數(shù)的第二個(gè)參數(shù)規(guī)定了內(nèi)核要為該套接字排隊(duì)的最大連接個(gè)數(shù)。
#include <sys/socket.h>
int accept(int sockfd,struct sockaddr* cliaddr,socklen_t *addrlen);//成功返回描述符,失敗返回-1
//1,、如果第二三個(gè)參數(shù)為空,代表了,,我們對(duì)客戶的身份不感興趣,因此置為NULL,;
//2,、第一個(gè)參數(shù)為socket創(chuàng)建的監(jiān)聽套接字,返回的是已連接套接字,,兩個(gè)套接字是有區(qū)別的,,而且非常重要。區(qū)別:我們所創(chuàng)建的監(jiān)聽套接字一般服務(wù)器只創(chuàng)建一個(gè),并且一直存在,。而內(nèi)核會(huì)為每一個(gè)服務(wù)器進(jìn)程的客戶連接建立一個(gè)連接套接字,,當(dāng)服務(wù)器完成對(duì)某個(gè)給定客戶的服務(wù)時(shí),,連接套接字就會(huì)被關(guān)閉。

  

      

  總結(jié):我們學(xué)校的實(shí)驗(yàn)室是云計(jì)算實(shí)驗(yàn)室,,有很多的集群,,我在上面開了2臺(tái)虛擬機(jī),,在兩臺(tái)Linux系統(tǒng)上跑,??梢猿晒邮铡V灰獙P設(shè)置好即可,,注意,關(guān)掉防火墻:service iptables stop;

  > 3,、關(guān)于連接三次握手和TCP連接關(guān)閉時(shí)候的分組交換

  三次握手:

  為了更好的理解connect、bind、close三個(gè)函數(shù),了解一下TCP連接的建立和終止是很有必要的,。(請(qǐng)務(wù)必理解理解上面的所有的函數(shù)后,,再看這節(jié)),。

  1,、服務(wù)器首先必須被打開,等待準(zhǔn)備接受外來的連接,。我們上面的例子用到了socket,、bind,、listen這3個(gè)函數(shù),。之后,我們稱為服務(wù)端被被動(dòng)打開了。

  2,、客戶端是通過connect發(fā)起主動(dòng)打開,。

  

      3,、主動(dòng)打開后,,客戶TCP發(fā)送了一個(gè)SYN(同步)分節(jié),,它告訴服務(wù)器客戶將在連接中只發(fā)送的數(shù)據(jù)的初始序列號(hào),SYN分節(jié)不攜帶數(shù)據(jù),。它發(fā)送的IP數(shù)據(jù)報(bào),,只有一個(gè)IP首部、一個(gè)TCP首部以及TCP選項(xiàng),。

  4,、服務(wù)器必須確認(rèn)(ACK)客戶的SYN,,同時(shí)自己也發(fā)送一個(gè)SYN分節(jié),,它含有服務(wù)器將在同一連接中發(fā)送的數(shù)據(jù)的初始序列號(hào),。服務(wù)器在單個(gè)分節(jié)中發(fā)送SYN和對(duì)客戶SYN的ACK確認(rèn)(+1),。

  5、客戶必須確認(rèn)服務(wù)器的SYN分節(jié),。

  上面的過程稱為TCP的三次握手。

    注:SYN(synchronous)是TCP/IP建立連接時(shí)使用的握手信號(hào),。在客戶機(jī)和服務(wù)器之間建立正常的TCP網(wǎng)絡(luò)連接時(shí),,客戶機(jī)首先發(fā)出一個(gè)SYN消息,,服務(wù)器使用SYN+ACK應(yīng)答表示接收到了這個(gè)消息,最后客戶機(jī)再以ACK消息響應(yīng),。這樣在客戶機(jī)和服務(wù)器之間才能建立起可靠的TCP連接,,數(shù)據(jù)才可以在客戶機(jī)和服務(wù)器之間傳遞

 

  TCP連接終止

  終止一個(gè)連接需要4個(gè)分節(jié)。

  1,、通過調(diào)用close,,我們執(zhí)行主動(dòng)關(guān)閉,,TCP發(fā)送一個(gè)FIN(finish,表示結(jié)束),,表示數(shù)據(jù)發(fā)送完畢。

  2,、對(duì)端接收到FIN后,,執(zhí)行被動(dòng)關(guān)閉。

    3,、一段時(shí)候后,,接收到文件結(jié)束符的應(yīng)用進(jìn)程,將調(diào)用close關(guān)閉它的套接字,。于是套接字也發(fā)送一個(gè)了FIN,。

  4、確認(rèn)這個(gè)FIN ACK+1   下圖很清楚的表達(dá)了,?! ?/span>

  5、我們也稱它為TCP四次握手,。

  

      > 4,、IPv4、IPv6套接字的地址結(jié)構(gòu)

  IPv4地址結(jié)構(gòu): 

復(fù)制代碼
 1 struct in_addr {
 2    in_addr_t  s_addr;  
 3 };
 4 
 5 struct sockaddr_in {
 6    uint8_t sin_len; //無符號(hào)8位整型
 7    sa_family_t sin_famliy;  /*AF_INET*/
 8    in_port_t  sin_port;     
9 struct in_addr sin_addr; /*32位 IPv4 地址*/
10 char sin_zero[8]; /*unuse*/ 11 };
//頭文件 #include <sys/types.h>
//sa_family_t和socklen_t 頭文件 #include <sys/socket.h>
//in_addr_t in_port_t 頭文件 #include <netinet/in.h>
復(fù)制代碼

 

  IPv6地址結(jié)構(gòu):

復(fù)制代碼
struct in6_addr {
   uint8_t  s6_addr[16];  
};

#define SIN6_LEN

struct sockaddr_in6 {
   uint8_t sin6_len;
   sa_family_t sin6_famliy;
   in_port_t  sin6_port;

   uint32_t sin6_flowinfo;
   struct in6_addr sin6_addr;

   uint32_t sin6_scope_id;   
};
復(fù)制代碼

 

  > 5,、一些好的學(xué)習(xí)網(wǎng)站總結(jié)

  1,、關(guān)于51CTO上的這個(gè)視頻http://edu.51cto.com/course/course_id-903.html,我買了,,但是講的非常爛,,建議大家不要購(gòu)買。教課的老師也就是照著書念,,還不如自己,。浪費(fèi)錢。

  2,、http://www.cnblogs.com/skynet/archive/2010/12/12/1903949.html 

       http://blog.csdn.net/hguisu/article/details/7445768/

     http://www.oschina.net/code/snippet_97047_675

           這幾篇博客不錯(cuò),,能帶你入門。

  > 6,、代碼下載

  Githubhttps://github.com/micwu/Demo

  > 7,、總結(jié)

   學(xué)習(xí)之路是很蠻長(zhǎng)的。想要學(xué)好,,非常難,,需要長(zhǎng)期的積累。我也正在學(xué)習(xí)中,。經(jīng)過了很多的挫折,,但是有理想,,就一定能成功。希望大家想走Linux下服務(wù)器編程的同志們,,一起加油吧,。

  > 8、echo實(shí)現(xiàn)

  

  代碼下載:Github

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多