青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

開源之路

憶往昔, 項羽不過江. 江東好風光! 今振臂一呼,率甲三千, 試問天!
posts - 86, comments - 55, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

Linux 下Socket編程基礎

Posted on 2006-07-18 13:58 江邊之鳥 閱讀(346) 評論(0)  編輯 收藏 引用

1、 引言

Linux的興起可以說是Internet創(chuàng)造的一個奇跡。Linux作為一個完全開放其原代碼的免費的自由軟件,兼容了各種UNIX標準(如POSIX、UNIX System V 和 BSD UNIX 等)的多用戶、多任務的具有復雜內核的操作系統(tǒng)。在中國,隨著Internet的普及,一批主要以高等院校的學生和ISP的技術人員組成的Linux愛好者隊伍已經蓬勃成長起來。越來越多的編程愛好者也逐漸酷愛上這個優(yōu)秀的自由軟件。本文介紹了Linux下Socket的基本概念和函數調用。

2、 什么是Socket

Socket(套接字)是通過標準的UNIX文件描述符和其它程序通訊的一個方法。每一個套接字都用一個半相關描述:{協議,本地地址、本地端口}來表示;一個完整的套接字則用一個相關描述:{協議,本地地址、本地端口、遠程地址、遠程端口},每一個套接字都有一個本地的由操作系統(tǒng)分配的唯一的套接字號。

3、 Socket的三種類型

(1) 流式Socket(SOCK_STREAM)

流式套接字提供可靠的、面向連接的通信流;它使用TCP協議,從而保證了數據傳輸的正確性和順序的。

(2) 數據報Socket(SOCK_DGRAM)

數據報套接字定義了一種無連接的服務,數據通過相互獨立的報文進行傳輸,是無序的,并且不保證可靠、無差錯。它使用數據報協議UDP

(3) 原始Socket

原始套接字允許對底層協議如IP或ICMP直接訪問,它功能強大但使用較為不便,主要用于一些協議的開發(fā)。

4、 利用套接字發(fā)送數據

1、 對于流式套接字用系統(tǒng)調用send()來發(fā)送數據。

2、 對于數據報套接字,則需要自己先加一個信息頭,然后調用sendto()函數把數據發(fā)送出去。

5、 Linux中Socket的數據結構

(1) struct sockaddr { //用于存儲套接字地址

unsigned short sa_family;//地址類型

char sa_data[14]; //14字節(jié)的協議地址

};

(2) struct sockaddr_in{ //in 代表internet

short int sin_family; //internet協議族

unsigned short int sin_port;//端口號,必須是網絡字節(jié)順序

struct in_addr sin_addr;//internet地址,必須是網絡字節(jié)順序

unsigned char sin_zero;//添0(和struct sockaddr一樣大小

};

(3) struct in_addr{

unsigned long s_addr;

};

6、 網絡字節(jié)順序及其轉換函數

(1) 網絡字節(jié)順序

每一臺機器內部對變量的字節(jié)存儲順序不同,而網絡傳輸的數據是一定要統(tǒng)一順序的。所以對內部字節(jié)表示順序與網絡字節(jié)順序不同的機器,一定要對數據進行轉換,從程序的可移植性要求來講,就算本機的內部字節(jié)表示順序與網絡字節(jié)順序相同也應該在傳輸數據以前先調用數據轉換函數,以便程序移植到其它機器上后能正確執(zhí)行。真正轉換還是不轉換是由系統(tǒng)函數自己來決定的。

(2) 有關的轉換函數

* unsigned short int htons(unsigned short int hostshort):

主機字節(jié)順序轉換成網絡字節(jié)順序,對無符號短型進行操作4bytes

* unsigned long int htonl(unsigned long int hostlong):

主機字節(jié)順序轉換成網絡字節(jié)順序,對無符號長型進行操作8bytes

* unsigned short int ntohs(unsigned short int netshort):

網絡字節(jié)順序轉換成主機字節(jié)順序,對無符號短型進行操作4bytes

* unsigned long int ntohl(unsigned long int netlong):

網絡字節(jié)順序轉換成主機字節(jié)順序,對無符號長型進行操作8bytes

注:以上函數原型定義在netinet/in.h里

7、 IP地址轉換

有三個函數將數字點形式表示的字符串IP地址與32位網絡字節(jié)順序的二進制形式的IP地址進行轉換

(1) unsigned long int inet_addr(const char * cp):該函數把一個用數字和點表示的IP地址的字符串轉換成一個無符號長整型,如:struct sockaddr_in ina

ina.sin_addr.s_addr=inet_addr("202.206.17.101")

該函數成功時:返回轉換結果;失敗時返回常量INADDR_NONE,該常量=-1,二進制的無符號整數-1相當于255.255.255.255,這是一個廣播地址,所以在程序中調用iner_addr()時,一定要人為地對調用失敗進行處理。由于該函數不能處理廣播地址,所以在程序中應該使用函數inet_aton()。

(2)int inet_aton(const char * cp,struct in_addr * inp):此函數將字符串形式的IP地址轉換成二進制形式的IP地址;成功時返回1,否則返回0,轉換后的IP地址存儲在參數inp中。

(3) char * inet_ntoa(struct in-addr in):將32位二進制形式的IP地址轉換為數字點形式的IP地址,結果在函數返回值中返回,返回的是一個指向字符串的指針。

8、 字節(jié)處理函數

Socket地址是多字節(jié)數據,不是以空字符結尾的,這和C語言中的字符串是不同的。Linux提供了兩組函數來處理多字節(jié)數據,一組以b(byte)開頭,是和BSD系統(tǒng)兼容的函數,另一組以mem(內存)開頭,是ANSI C提供的函數。

以b開頭的函數有:

(1) void bzero(void * s,int n):將參數s指定的內存的前n個字節(jié)設置為0,通常它用來將套接字地址清0。

(2) void bcopy(const void * src,void * dest,int n):從參數src指定的內存區(qū)域拷貝指定數目的字節(jié)內容到參數dest指定的內存區(qū)域。

(3) int bcmp(const void * s1,const void * s2,int n):比較參數s1指定的內存區(qū)域和參數s2指定的內存區(qū)域的前n個字節(jié)內容,如果相同則返回0,否則返回非0。

注:以上函數的原型定義在strings.h中。

以mem開頭的函數有:

(1) void * memset(void * s,int c,size_t n):將參數s指定的內存區(qū)域的前n個字節(jié)設置為參數c的內容。

(2) void * memcpy(void * dest,const void * src,size_t n):功能同bcopy(),區(qū)別:函數bcopy()能處理參數src和參數dest所指定的區(qū)域有重疊的情況,memcpy()則不能。

(4) int memcmp(const void * s1,const void * s2,size_t n):比較參數s1和參數s2指定區(qū)域的前n個字節(jié)內容,如果相同則返回0,否則返回非0。

注:以上函數的原型定義在string.h中。

9、 基本套接字函數

(1) socket()

#include<sys/types.h>

#include<sys/socket.h>

int socket(int domain,int type,int protocol)

參數domain指定要創(chuàng)建的套接字的協議族,可以是如下值:

AF_UNIX //UNIX域協議族,本機的進程間通訊時使用

AF_INET //Internet協議族(TCP/IP)

AF_ISO //ISO協議族

參數type指定套接字類型,可以是如下值:

SOCK_STREAM //流套接字,面向連接的和可靠的通信類型

SOCK_DGRAM //數據報套接字,非面向連接的和不可靠的通信類型

SOCK_RAW //原始套接字,只對Internet協議有效,可以用來直接訪問IP協議

參數protocol通常設置成0,表示使用默認協議,如Internet協議族的流套接字使用TCP協議,而數據報套接字使用UDP協議。當套接字是原始套接字類型時,需要指定參數protocol,因為原始套接字對多種協議有效,如ICMP和IGMP等。

Linux系統(tǒng)中創(chuàng)建一個套接字的操作主要是:在內核中創(chuàng)建一個套接字數據結構,然后返回一個套接字描述符標識這個套接字數據結構。這個套接字數據結構包含連接的各種信息,如對方地址、TCP狀態(tài)以及發(fā)送和接收緩沖區(qū)等等,TCP協議根據這個套接字數據結構的內容來控制這條連接。

(2) 函數connect()

#include<sys/types.h>

#include<sys/socket.h>

int connect(int sockfd,struct sockaddr * servaddr,int addrlen)

參數sockfd是函數socket返回的套接字描述符;參數servaddr指定遠程服務器的套接字地址,包括服務器的IP地址和端口號;參數addrlen指定這個套接字地址的長度。成功時返回0,否則返回-1,并設置全局變量為以下任何一種錯誤類型:ETIMEOUT、ECONNREFUSED、EHOSTUNREACH或ENETUNREACH。

在調用函數connect之前,客戶機需要指定服務器進程的套接字地址。客戶機一般不需要指定自己的套接字地址(IP地址和端口號),系統(tǒng)會自動從1024至5000的端口號范圍內為它選擇一個未用的端口號,然后以這個端口號和本機的IP地址填充這個套接字地址。

客戶機調用函數connect來主動建立連接。這個函數將啟動TCP協議的3次握手過程。在建立連接之后或發(fā)生錯誤時函數返回。連接過程可能出現的錯誤情況有:

(1) 如果客戶機TCP協議沒有接收到對它的SYN數據段的確認,函數以錯誤返回,錯誤類型為ETIMEOUT。通常TCP協議在發(fā)送SYN數據段失敗之后,會多次發(fā)送SYN數據段,在所有的發(fā)送都高中失敗之后,函數以錯誤返回。

注:SYN(synchronize)位:請求連接。TCP用這種數據段向對方TCP協議請求建立連接。在這個數據段中,TCP協議將它選擇的初始序列號通知對方,并且與對方協議協商最大數據段大小。SYN數據段的序列號為初始序列號,這個SYN數據段能夠被確認。當協議接收到對這個數據段的確認之后,建立TCP連接。

(2) 如果遠程TCP協議返回一個RST數據段,函數立即以錯誤返回,錯誤類型為ECONNREFUSED。當遠程機器在SYN數據段指定的目的端口號處沒有服務進程在等待連接時,遠程機器的TCP協議將發(fā)送一個RST數據段,向客戶機報告這個錯誤。客戶機的TCP協議在接收到RST數據段后不再繼續(xù)發(fā)送SYN數據段,函數立即以錯誤返回。

注:RST(reset)位:表示請求重置連接。當TCP協議接收到一個不能處理的數據段時,向對方TCP協議發(fā)送這種數據段,表示這個數據段所標識的連接出現了某種錯誤,請求TCP協議將這個連接清除。有3種情況可能導致TCP協議發(fā)送RST數據段:(1)SYN數據段指定的目的端口處沒有接收進程在等待;(2)TCP協議想放棄一個已經存在的連接;(3)TCP接收到一個數據段,但是這個數據段所標識的連接不存在。接收到RST數據段的TCP協議立即將這條連接非正常地斷開,并向應用程序報告錯誤。

(3) 如果客戶機的SYN數據段導致某個路由器產生“目的地不可到達”類型的ICMP消息,函數以錯誤返回,錯誤類型為EHOSTUNREACH或ENETUNREACH。通常TCP協議在接收到這個ICMP消息之后,記錄這個消息,然后繼續(xù)幾次發(fā)送SYN數據段,在所有的發(fā)送都告失敗之后,TCP協議檢查這個ICMP消息,函數以錯誤返回。

注:ICMP:Internet 消息控制協議。Internet的運行主要是由Internet的路由器來控制,路由器完成IP數據包的發(fā)送和接收,如果發(fā)送數據包時發(fā)生錯誤,路由器使用ICMP協議來報告這些錯誤。ICMP數據包是封裝在IP數據包的數據部分中進行傳輸的,其格式如下:

類型

校驗和

數據

0 8 16 24 31

類型:指出ICMP數據包的類型。

代碼:提供ICMP數據包的進一步信息。

校驗和:提供了對整個ICMP數據包內容的校驗和。

ICMP數據包主要有以下類型:

(1) 目的地不可到達:A、目的主機未運行;B、目的地址不存在;C、路由表中沒有目的地址對應的條目,因而路由器無法找到去往目的主機的路由。

(2) 超時:路由器將接收到的IP數據包的生存時間(TTL)域減1,如果這個域的值變?yōu)?,路由器丟棄這個IP數據包,并且發(fā)送這種ICMP消息。

(3) 參數出錯:當IP數據包中有無效域時發(fā)送。

(4) 重定向:將一條新的路徑通知主機。

(5) ECHO請求、ECHO回答:這兩條消息用語測試目的主機是否可以到達。請求者向目的主機發(fā)送ECHO請求ICMP數據包,目的主機在接收到這個ICMP數據包之后,返回ECHO回答ICMP數據包。

(6) 時戳請求、時戳回答:ICMP協議使用這兩種消息從其他機器處獲得其時鐘的當前時間。

調用函數connect的過程中,當客戶機TCP協議發(fā)送了SYN數據段的確認之后,TCP狀態(tài)由CLOSED狀態(tài)轉為SYN_SENT狀態(tài),在接收到對SYN數據段的確認之后,TCP狀態(tài)轉換成ESTABLISHED狀態(tài),函數成功返回。如果調用函數connect失敗,應該用close關閉這個套接字描述符,不能再次使用這個套接字描述符來調用函數connect。

注:TCP協議狀態(tài)轉換圖:

被動OPEN CLOSE 主動OPEN

(建立TCB) (刪除TCB) (建立TCB,

發(fā)送SYN)

接收SYN SEND

(發(fā)送SYN,ACK) (發(fā)送SYN)

接收SYN的ACK(無動作)

接收SYN的ACK 接收SYN,ACK

(無動作) (發(fā)送ACK)

CLOSE

(發(fā)送FIN) CLOSE 接收FIN

(發(fā)送FIN) (發(fā)送FIN)

接收FIN

接收FIN的ACK(無動作) (發(fā)送ACK) CLOSE(發(fā)送FIN)

接收FIN 接收FIN的ACK 接收FIN的ACK

(發(fā)送ACK) (無動作) (無動作)

2MSL超時(刪除TCB)

(3) 函數bind()

函數bind將本地地址與套接字綁定在一起,其定義如下:

#include<sys/types.h>

#include<sys/socket.h>

int bind(int sockfd,struct sockaddr * myaddr,int addrlen);

參數sockfd是函數sockt返回的套接字描述符;參數myaddr是本地地址;參數addrlen是套接字地址結構的長度。執(zhí)行成功時返回0,否則,返回-1,并設置全局變量errno為錯誤類型EADDRINUSER。

服務器和客戶機都可以調用函數bind來綁定套接字地址,但一般是服務器調用函數bind來綁定自己的公認端口號。綁定操作一般有如下幾種組合方式:

表1

程序類型

IP地址

端口號

說明

服務器

INADDR_ANY

非零值

指定服務器的公認端口號

服務器

本地IP地址

非零值

指定服務器的IP地址和公認端口號

客戶機

INADDR_ANY

非零值

指定客戶機的連接端口號

客戶機

本地IP地址

非零值

指定客戶機的IP地址連接端口號

客戶機

本地IP地址

指定客戶機的IP地址

分別說明如下:

(1) 服務器指定套接字地址的公認端口號,不指定IP地址:即服務器調用bind時,設置套接字的IP地址為特殊的INADDE-ANY,表示它愿意接收來自任何網絡設備接口的客戶機連接。這是服務器最常用的綁定方式。

(2) 服務器指定套接字地址的公認端口號和IP地址:服務器調用bind時,如果設置套接字的IP地址為某個本地IP地址,這表示這臺機器只接收來自對應于這個IP地址的特定網絡設備接口的客戶機連接。當服務器有多塊網卡時,可以用這種方式來限制服務器的接收范圍。

(3) 客戶機指定套接字地址的連接端口號:一般情況下,客戶機調用connect函數時不用指定自己的套接字地址的端口號。系統(tǒng)會自動為它選擇一個未用的端口號,并且用本地的IP地址來填充套接字地址中的相應項。但有時客戶機需要使用一個特定的端口號(比如保留端口號),而系統(tǒng)不會未客戶機自動分配一個保留端口號,所以需要調用函數bind來和一個未用的保留端口號綁定。

(4) 指定客戶機的IP地址和連接端口號:表示客戶機使用指定的網絡設備接口和端口號進行通信。

(5) 指定客戶機的IP地址:表示客戶機使用指定的網絡設備接口和端口號進行通信,系統(tǒng)自動為客戶機選一個未用的端口號。一般只有在主機有多個網絡設備接口時使用。

我們一般不在客戶機上使用固定的客戶機端口號,除非是必須使用的情況。在客戶機上使用固定的端口號有以下不利:

(1) 服務器執(zhí)行主動關閉操作:服務器最后進入TIME_WAIT狀態(tài)。當客戶機再次與這個服務器進行連接時,仍使用相同的客戶機端口號,于是這個連接與前次連接的套接字對完全一樣,但是一呢、為前次連接處于TIME_WAIT狀態(tài),并未消失,所以這次連接請求被拒絕,函connect以錯誤返回,錯誤類型為ECONNREFUSED

(2) 客戶機執(zhí)行主動關閉操作:客戶機最后進入TIME_WAIT狀態(tài)。當馬上再次執(zhí)行這個客戶機程序時,客戶機將繼續(xù)與這個固定客戶機端口號綁定,但因為前次連接處于TIME_WAIT狀態(tài),并未消失,系統(tǒng)會發(fā)現這個端口號仍被占用,所以這次綁定操作失敗,函數bind以錯誤返回,錯誤類型為EADDRINUSE。

(4) 函數listen()

函數listen將一個套接字轉換為征聽套接字,定義如下;

#include<sys/socket,h>

int listen(int sockfd,int backlog)

參數sockfd指定要轉換的套接字描述符;參數backlog設置請求隊列的最大長度;執(zhí)行成功時返回0, 否則返回-1。函數listen功能有兩個:

(1) 將一個尚未連接的主動套接字(函數socket創(chuàng)建的可以用來進行主動連接但不能接受連接請求的套接字)轉換成一個被動連接套接字。執(zhí)行l(wèi)isten之后,服務器的TCP狀態(tài)由CLOSED轉為LISTEN狀態(tài)。

(2) TCP協議將到達的連接請求隊列,函數listen的第二個參數指定這個隊列的最大長度。

注:參數backlog的作用:

TCP協議為每一個征聽套接字維護兩個隊列:

(1) 未完成連接隊列:每個尚未完成3次握手操作的TCP連接在這個隊列中占有一項。TCP希望儀在接收到一個客戶機SYN數據段之后,在這個隊列中創(chuàng)建一個新條目,然后發(fā)送對客戶機SYN數據段的確認和自己的SYN數據段(ACK+SYN數據段),等待客戶機對自己的SYN數據段的確認。此時,套接字處于SYN_RCVD狀態(tài)。這個條目將保存在這個隊列中,直到客戶機返回對SYN數據段的確認或者連接超時。

(2) 完成連接隊列:每個已經完成3次握手操作,但尚未被應用程序接收(調用函數accept)的TCP連接在這個隊列中占有一項。當一個在未完成連接隊列中的連接接收到對SYN數據段的確認之后,完成3次握手操作,TCP協議將它從未完成連接隊列移到完成連接隊列中。此時,套接字處于ESTABLISHED狀態(tài)。這個條目將保存在這個隊列中,直到應用程序調用函數accept來接收它。

參數backlog指定某個征聽套接字的完成連接隊列的最大長度,表示這個套接字能夠接收的最大數目的未接收連接。如果當一個客戶機的SYN數據段到達時,征聽套接字的完成隊列已經滿了,那么TCP協議將忽略這個SYN數據段。對于不能接收的SYN數據段,TCP協議不發(fā)送RST數據段,

(5) 函數accept()

函數accept從征聽套接字的完成隊列中接收一個已經建立起來的TCP連接。如果完成連接隊列為空,那么這個進程睡眠。

#include<sys/socket.h>

int accept(int sockfd,struct sockaddr * addr,int * addrlen)

參數sockfd指定征聽套接字描述符;參數addr為指向一個Internet套接字地址結構的指針;參數addrlen為指向一個整型變量的指針。執(zhí)行成功時,返回3個結果:函數返回值為一個新的套接字描述符,標識這個接收的連接;參數addr指向的結構變量中存儲客戶機地址;參數addrlen指向的整型變量中存儲客戶機地址的長度。失敗時返回-1。

征聽套接字專為接收客戶機連接請求,完成3次握手操作而用的,所以TCP協議不能使用征聽套接字描述符來標識這個連接,于是TCP協議創(chuàng)建一個新的套接字來標識這個要接收的連接,并將它的描述符發(fā)揮給應用程序。現在有兩個套接字,一個是調用函數accept時使用的征聽套接字,另一個是函數accept返回的連接套接字(connected socket)。一個服務器通常只需創(chuàng)建一個征聽套接字,在服務器進程的整個活動期間,用它來接收所有客戶機的連接請求,在服務器進程終止前關閉這個征聽套接字;對于沒一個接收的(accepted)連接,TCP協議都創(chuàng)建一個新的連接套接字來標識這個連接,服務器使用這個連接套接字與客戶機進行通信操作,當服務器處理完這個客戶機請求時,關閉這個連接套接字。

當函數accept阻塞等待已經建立的連接時,如果進程捕獲到信號,函數將以錯誤返回,錯誤類型為EINTR。對于這種錯誤,一般重新調用函數accept來接收連接。

(6) 函數close()

函數close關閉一個套接字描述符。定義如下:

#include<unistd.h>

int close(int sockfd);

執(zhí)行成功時返回0,否則返回-1。與操作文件描述符的close一樣,函數close將套接字描述符的引用計數器減1,如果描述符的引用計數大于0,則表示還有進程引用這個描述符,函數close正常返回;如果為0,則啟動清除套接字描述符的操作,函數close立即正常返回。

調用close之后,進程將不再能夠訪問這個套接字,但TCP協議將繼續(xù)使用這個套接字,將尚未發(fā)送的數據傳遞到對方,然后發(fā)送FIN數據段,執(zhí)行關閉操作,一直等到這個TCP連接完全關閉之后,TCP協議才刪除該套接字。

(7) 函數read()和write()

用于從套接字讀寫數據。定義如下:

int read(int fd,char * buf,int len)

int write(int fd,char * buf,int len)

函數執(zhí)行成功時,返回讀或寫的數據量的大小,失敗時返回-1。

每個TCP套接字都有兩個緩沖區(qū):套接字發(fā)送緩沖區(qū)、套接字接收緩沖區(qū),分別處理發(fā)送和接收任務。從網絡讀、寫數據的操作是由TCP協議在內核中完成的:TCP協議將從網絡上接收到的數據保存在相應套接字的接收緩沖區(qū)中,等待用戶調用函數將它們從接收緩沖區(qū)拷貝到用戶緩沖區(qū);用戶將要發(fā)送的數據拷貝到相應套接字的發(fā)送緩沖區(qū)中,然后由TCP協議按照一定的算法處理這些數據。

讀寫連接套接字的操作與讀寫文件的操作類似,也可以使用函數read和write。函數read完成將數據從套接字接收緩沖區(qū)拷貝到用戶緩沖區(qū):當套接字接收緩沖區(qū)有數據可讀時,1:可讀數據量大于函數read指定值,返回函數參數len指定的數據量;2:了度數據量小于函數read指定值,函數read不等待請求的所有數據都到達,而是立即返回實際讀到的數據量;當無數據可讀時,函數read將阻塞不返回,等待數據到達。

當TCP協議接收到FIN數據段,相當于給讀操作一個文件結束符,此時read函數返回0,并且以后所有在這個套接字上的讀操作均返回0,這和普通文件中遇到文件結束符是一樣的。

當TCP協議接收到RST數據段,表示連接出現了某種錯誤,函數read將以錯誤返回,錯誤類型為ECONNERESET。并且以后所有在這個套接字上的讀操作均返回錯誤。錯誤返回時返回值小于0。

函數write完成將數據從用戶緩沖區(qū)拷貝到套接字發(fā)送緩沖區(qū)的任務:到套接字發(fā)送緩沖區(qū)有足夠拷貝所有用戶數據的空間時,函數write將數據拷貝到這個緩沖區(qū)中,并返回老輩的數量大小,如果可用空間小于write參數len指定的大小時,函數write將阻塞不返回,等待緩沖區(qū)有足夠的空間。

當TCP協議接收到RST數據段(當對方已經關閉了這條連接之后,繼續(xù)向這個套接字發(fā)送數據將導致對方TCP協議返回RST數據段),TCP協議接收到RST數據段時,函數write將以錯誤返回,錯誤類型為EINTR。以后可以繼續(xù)在這個套接字上寫數據。

(8) 函數getsockname()和getpeername()

函數getsockname返回套接字的本地地址;函數getpeername返回套接字對應的遠程地址。

10、 結束語

網絡程序設計全靠套接字接收和發(fā)送信息。上文主要講述了Linux 下Socket的基本概念、Sockets API以及Socket所涉及到的TCP常識。


只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品国产成人| 久久精品国产成人| 欧美精品久久久久久久久老牛影院| 欧美极品在线观看| 99视频有精品| 麻豆成人精品| 国内精品久久久久影院优 | 国产在线精品二区| 亚洲福利视频一区二区| 国产欧美一区二区三区国产幕精品| 欧美日韩mp4| 久久av老司机精品网站导航| 亚洲一区二区网站| 亚洲影院在线| 欧美在线综合| 久久精品国产91精品亚洲| 欧美亚洲一区| 亚洲精品在线三区| 一区二区冒白浆视频| 久久综合九色| 在线观看精品| 久久伊人免费视频| 美女视频黄a大片欧美| 亚洲乱码国产乱码精品精98午夜 | 亚洲三级免费观看| 欧美成人精品一区二区三区| 亚洲免费网站| 欧美特黄一级| 久久免费国产精品| 欧美国产丝袜视频| 美女成人午夜| 中文av一区二区| 久久久五月婷婷| 亚洲一区国产一区| 亚洲日本成人| 亚洲精品在线电影| 欧美特黄一级| 麻豆亚洲精品| 亚洲高清色综合| av不卡在线看| 亚洲欧洲日韩在线| 性欧美办公室18xxxxhd| 亚洲网站在线看| 欧美日韩精品免费观看视频完整 | 久久野战av| 久久久欧美精品| 国内精品久久久| 嫩草伊人久久精品少妇av杨幂| 久久亚洲午夜电影| 国内精品久久久久久久影视麻豆 | 亚洲成在线观看| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲毛片在线观看.| 午夜一区二区三区不卡视频| 亚洲女女女同性video| 久久夜色精品| 亚洲第一级黄色片| 国产精品美女久久久久久久 | 亚洲黄色免费电影| 欧美一区二区三区免费在线看| 亚洲男人的天堂在线观看| 欧美激情一二三区| 欧美午夜精品理论片a级按摩| 久久国产精品亚洲va麻豆| 欧美噜噜久久久xxx| 亚洲福利视频网| 99视频+国产日韩欧美| 欧美激情一区二区三区蜜桃视频 | 亚洲日本中文字幕| 国产欧美日韩精品a在线观看| 久久成人羞羞网站| 一区二区不卡在线视频 午夜欧美不卡在| 亚洲精品美女在线观看| 国产精品一区一区| 欧美日韩国产页| 欧美成人午夜免费视在线看片| 亚洲深夜福利在线| 亚洲精品日产精品乱码不卡| 欧美专区福利在线| 性做久久久久久久免费看| 亚洲国产另类精品专区| 欧美日本不卡| 久热精品在线| 亚洲视频大全| 久久久国产亚洲精品| 亚洲欧洲日夜超级视频| 欧美日韩少妇| 模特精品在线| 欧美jjzz| 欧美主播一区二区三区| 久久综合网色—综合色88| 99精品久久久| 国产一区二区三区的电影| 欧美专区在线| 一区二区高清视频| 久久网站免费| 欧美日韩国产一区二区| 亚洲一区图片| 亚洲看片网站| 99re6热只有精品免费观看| 亚洲高清在线观看一区| 亚洲欧美综合国产精品一区| 亚洲国产精品一区二区尤物区| 欧美日本韩国一区| 欧美华人在线视频| 欧美成人午夜视频| 欧美日韩美女| 国产精品家庭影院| 国产专区综合网| 亚洲美女视频在线免费观看| 一区二区三区免费看| 欧美在线免费一级片| 蘑菇福利视频一区播放| 麻豆精品网站| 欧美不卡一区| 免费亚洲网站| 欧美va天堂va视频va在线| 亚洲欧洲99久久| 久久久久国色av免费看影院| 久久九九免费| 亚洲摸下面视频| 欧美福利视频网站| 欧美在线啊v| 欧美日韩1区2区| 亚洲成人资源| 欧美亚洲尤物久久| 在线亚洲成人| 久久影院亚洲| 国产精品亚洲视频| 亚洲一区二区三区在线播放| 久久久亚洲国产天美传媒修理工| 美女久久网站| 久久久一本精品99久久精品66| 欧美人交a欧美精品| 国产精品一卡二| 亚洲国产视频a| 亚洲国产一区二区三区高清| 日韩一二三区视频| 国产精品每日更新| 午夜精品剧场| 亚洲国产91| 欧美精品系列| 亚洲人成网站在线观看播放| 国模套图日韩精品一区二区| 欧美一区二区三区男人的天堂 | 亚洲视频在线观看视频| 一区二区三区欧美激情| 国产精品乱人伦一区二区| 久久久久久久久岛国免费| 一区二区欧美国产| 男人插女人欧美| 欧美一区二区高清在线观看| 欧美在线三级| 一区二区三区四区精品| 亚洲黄色在线| 国产精品久久久免费| 欧美精品一区二区精品网| 欧美日本高清视频| 欧美大胆成人| 欧美另类99xxxxx| 欧美精品免费在线观看| 亚洲伊人网站| 久久久成人网| 久久久久久久国产| 久久福利精品| 美国十次成人| 欧美伦理在线观看| 国产精品久久久久久久久久直播 | 在线亚洲一区观看| 99精品久久免费看蜜臀剧情介绍| 国内成人精品2018免费看| 欧美日韩大陆在线| 国产日韩欧美二区| 亚洲国产精品成人va在线观看| 黄色小说综合网站| 日韩视频在线观看免费| 亚洲视频中文字幕| 亚洲精品综合精品自拍| 99精品欧美一区二区三区 | 裸体一区二区三区| 久久久国产视频91| 蜜臀a∨国产成人精品| 久久综合亚州| 中文无字幕一区二区三区| 午夜日韩电影| 欧美激情1区| 国产精品人人做人人爽人人添 | 欧美精品色综合| 国产精品日韩在线一区| 国产一区二区三区在线观看网站 | 一区二区三区高清不卡| 亚洲成人直播| 欧美亚洲在线| 欧美激情麻豆| 欧美专区第一页| 久久国产精品久久精品国产| 久久久免费av| 国产精品二区在线观看| 亚洲国产二区| 亚洲欧美第一页|