【Linux网络编程】套接字简介
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 套接字屬性
- 03. socket函數(shù)
- 04. 套接字地址結(jié)構(gòu)
- 05. 附錄
01. 概述
Socket套接字由遠(yuǎn)景研究規(guī)劃局(Advanced Research Projects Agency, ARPA)資助加里福尼亞大學(xué)伯克利分校的一個(gè)研究組研發(fā)。其目的是將TCP/IP協(xié)議相關(guān)軟件移植到UNIX類系統(tǒng)中。設(shè)計(jì)者開發(fā)了一個(gè)接口,以便應(yīng)用程序能簡單地調(diào)用該接口通信。這個(gè)接口不斷完善,最終形成了Socket套接字。Linux系統(tǒng)采用了Socket套接字,因此,Socket接口就被廣泛使用,到現(xiàn)在已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn)。與套接字相關(guān)的函數(shù)被包含在頭文件sys/socket.h中。
Socket的英文原意是"插座",作為類UNIX系統(tǒng)的進(jìn)程通信機(jī)制,它如同插座一樣方便的幫助計(jì)算機(jī)接入互聯(lián)網(wǎng)通信。
任何用戶在通信之前,首先要先申請一個(gè)Socket號,Socket號相當(dāng)于自己的電話號碼。同時(shí)要知道對方的電話號碼,相當(dāng)于對方有一個(gè)Socket。然后向?qū)Ψ綋芴柡艚?#xff0c;相當(dāng)于發(fā)出連接請求(假如對方不在同一區(qū)內(nèi),還要撥對方區(qū)號,相當(dāng)于給出網(wǎng)絡(luò)地址)。對方假如在場并空閑(相當(dāng)于通信的另一主機(jī)開機(jī)且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當(dāng)于連接成功。雙方通話的過程,是向電話機(jī)發(fā)出信號和從電話機(jī)接受信號的過程,相當(dāng)于Socket發(fā)送數(shù)據(jù)和從Socket接受數(shù)據(jù)。通話結(jié)束后,一方掛起電話機(jī),相當(dāng)于關(guān)閉Socket,撤銷連接。
由此可見,Socket的通信機(jī)制與電話交換機(jī)制非常相似。Socket實(shí)質(zhì)上提供了進(jìn)程通信的端點(diǎn)。進(jìn)程通信之前,雙方首先必須各自創(chuàng)建一個(gè)端點(diǎn),否則是沒有辦法建立聯(lián)系并相互通信的。每一個(gè)Socket都用一個(gè)半相關(guān)描述。
一個(gè)完整的Socket則用一個(gè)相關(guān)描述:{協(xié)議,本地地址,本地端口}。
02. 套接字屬性
套接字的特性有三個(gè)屬性確定,它們是:域(domain),類型(type),和協(xié)議(protocol)。
套接字的域
域指定套接字通信中使用的網(wǎng)絡(luò)介質(zhì)。最常見的套接字域是 AF_INET,它是指 Internet 網(wǎng)絡(luò),許多 Linux 局域網(wǎng)使用的都是該網(wǎng)絡(luò),當(dāng)然,因特網(wǎng)自身用的也是它。
套接字類型
流套接字(SOCK_STREAM):
流套接字用于提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù)。該服務(wù)將保證數(shù)據(jù)能夠?qū)崿F(xiàn)無差錯(cuò)、無重復(fù)發(fā)送,并按順序接收。流套接字之所以能夠?qū)崿F(xiàn)可靠的數(shù)據(jù)服務(wù),原因在于其使用了傳輸控制協(xié)議,即TCP(The Transmission Control Protocol)協(xié)議。
數(shù)據(jù)報(bào)套接字(SOCK_DGRAM):
數(shù)據(jù)報(bào)套接字提供了一種無連接的服務(wù)。該服務(wù)并不能保證數(shù)據(jù)傳輸?shù)目煽啃?#xff0c;數(shù)據(jù)有可能在傳輸過程中丟失或出現(xiàn)數(shù)據(jù)重復(fù),且無法保證順序地接收到數(shù)據(jù)。數(shù)據(jù)報(bào)套接字使用UDP(User Datagram Protocol)協(xié)議進(jìn)行數(shù)據(jù)的傳輸。由于數(shù)據(jù)報(bào)套接字不能保證數(shù)據(jù)傳輸?shù)目煽啃?#xff0c;對于有可能出現(xiàn)的數(shù)據(jù)丟失情況,需要在程序中做相應(yīng)的處理。
原始套接字(SOCK_RAW):
原始套接字與標(biāo)準(zhǔn)套接字(標(biāo)準(zhǔn)套接字指的是前面介紹的流套接字和數(shù)據(jù)報(bào)套接字)的區(qū)別在于:原始套接字可以讀寫內(nèi)核沒有處理的IP數(shù)據(jù)包,而流套接字只能讀取TCP協(xié)議的數(shù)據(jù),數(shù)據(jù)報(bào)套接字只能讀取UDP協(xié)議的數(shù)據(jù)。因此,如果要訪問其他協(xié)議發(fā)送數(shù)據(jù)必須使用原始套接字。
套接字協(xié)議(協(xié)議類別)
只要底層的傳輸機(jī)制允許不止一個(gè)協(xié)議來提供要求的套接字類型,我們就可以為套接字選擇一個(gè)特定的協(xié)議。通常使用默認(rèn)即可(也就是最后一個(gè)參數(shù)填“0”)。
03. socket函數(shù)
#include <sys/types.h> /* See NOTES */ #include <sys/socket.h>int socket(int domain, int type, int protocol); 功能:創(chuàng)建一個(gè)用于網(wǎng)絡(luò)通信的 socket 套接字(描述符) 參數(shù):family:協(xié)議族(AF_UNIX、AF_INET、AF_INET6、PF_PACKET等)type:套接字類型(SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等)protocol:協(xié)議類別(0、IPPROTO_TCP、IPPROTO_UDP等),設(shè)為 0 表示使用默認(rèn)協(xié)議。 返回值:成功:套接字失敗(<0)最常見的套接字域是 AF_UNIX 和 AF_INET,前者用于通過 Unix 和 Linux 文件系統(tǒng)實(shí)現(xiàn)的本地套接字,后者用于 Unix 網(wǎng)絡(luò)套接字。AF_INET 套接字可以用于通過包括因特網(wǎng)在內(nèi)的 TCP/IP 網(wǎng)絡(luò)進(jìn)行通信的程序。微軟 Windows 系統(tǒng)的 winsock 接口也提供了對這個(gè)套接字域的訪問功能。
/** Address families.*/ #define AF_UNSPEC 0 /* unspecified */ #define AF_UNIX 1 /* local to host (pipes, portals) */ #define AF_INET 2 /* internetwork: UDP, TCP, etc. */ #define AF_IMPLINK 3 /* arpanet imp addresses */ #define AF_PUP 4 /* pup protocols: e.g. BSP */ #define AF_CHAOS 5 /* mit CHAOS protocols */ #define AF_IPX 6 /* IPX and SPX */ #define AF_NS 6 /* XEROX NS protocols */ #define AF_ISO 7 /* ISO protocols */ #define AF_OSI AF_ISO /* OSI is ISO */ #define AF_ECMA 8 /* european computer manufacturers */ #define AF_DATAKIT 9 /* datakit protocols */ #define AF_CCITT 10 /* CCITT protocols, X.25 etc */ #define AF_SNA 11 /* IBM SNA */ #define AF_DECnet 12 /* DECnet */ #define AF_DLI 13 /* Direct data link interface */ #define AF_LAT 14 /* LAT */ #define AF_HYLINK 15 /* NSC Hyperchannel */ #define AF_APPLETALK 16 /* AppleTalk */ #define AF_NETBIOS 17 /* NetBios-style addresses */ #define AF_VOICEVIEW 18 /* VoiceView */ #define AF_FIREFOX 19 /* FireFox */ #define AF_UNKNOWN1 20 /* Somebody is using this! */ #define AF_BAN 21 /* Banyan */#define AF_MAX 22套接字類型
/** Types*/ #define SOCK_STREAM 1 /* stream socket */ #define SOCK_DGRAM 2 /* datagram socket */ #define SOCK_RAW 3 /* raw-protocol interface */ #define SOCK_RDM 4 /* reliably-delivered message */ #define SOCK_SEQPACKET 5 /* sequenced packet stream */參考示例:
創(chuàng)建TCP套接字
#include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h>tcp_socket = socket(AF_INET, SOCK_STREAM, 0);創(chuàng)建UDP套接字
#include <sys/socket.h> #include <netinet/in.h> #include <netinet/udp.h>udp_socket = socket(AF_INET, SOCK_DGRAM, 0);04. 套接字地址結(jié)構(gòu)
每個(gè)套接字(端點(diǎn))都有其自己的地址格式,對于 AF_UNIX 套接字來說,它的地址由結(jié)構(gòu) sockaddr_un 來描述,該結(jié)構(gòu)體定義在頭文件 sys/un.h 中,如下:
struct sockaddr_un {sa_family_t sun_family; //套接字域char sun_path[];//名字 };而在 AF_INET 域中,套接字地址結(jié)構(gòu)由 sockaddr_in 來指定,該結(jié)構(gòu)體定義在頭文件 netinet/in.h 中:
struct sockaddr_in {short int sin_family;//套接字域unsigned short int sin_port;//端口struct in_addr sin_addr; //地址char sin_zero[8]; }IP 地址結(jié)構(gòu) sin_addr 被定義如下:
struct in_addr {unsigned long int s_addr; };05. 附錄
總結(jié)
以上是生活随笔為你收集整理的【Linux网络编程】套接字简介的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Linux网络编程】网络字节序和地址转
- 下一篇: linux 其他常用命令