Linux Network Programming —— Socket【Beta1 – Updating】

來源:互聯網
上載者:User
Linux Network Programming —— Socket

——by firo 2011.5.2

Cherish the memory of the Master —— W. Richard Stevens

Reference

man

Google

Understanding The Linux Kernel 3e 【ULK 3e】

Professional Linux Kernel Architecture 【PLKA】

Computer Systems: A Programmer‘s Perspective 2e 【CS:APP 2e】

Advanced Programming in the Unix Environment Second Edition 【APUE 2e】

Unix Network Programming The Sockets Networking API VOLUME 1 Third Edition 【UNPv1 3e】

The Linux Programming inTerface A Linux and UNIX System Programming Handbook 【TLPI】

卷首語

 

               Sockets are a method of IPC that allow data to be exchanged between applications,either on the same host (computer) or on different hosts connected by a network.

——by Michael Kerrisk author of TLPI

 

what is Socket?

【1】Socket: An interface between an application process and transport layer. 

【2】In Unix jargon, a socket is a file descriptor an integer associated with an open file.

【3】A socket is one endpoint of a two-way communication link between two programs running on the network. A socket is bound to a port  number so that the TCP layer can identify the application that data is destined to be sent.

【4】In computer networking, an Internet socket or network socket is an endpoint of a bidirectional inter-process communication flow  across an Internet Protocol-based computer network, such as theInternet.

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

socket()的三個參數【1】domain:地址族,用來指定Socket對應的本機地址格式和Socket使用的領域、範圍比如PF_PACKET和AF_UNIX都是用於本機資料轉送,而AF_INET和AF_INET6是通過Internet進行資料轉送的。【2】type:Socket類型SOCK_STREAM or SOCK_DGRAM等;結合地址族用來表明這個Socke的用途。【3】protocol:資料轉送遵守的協議、規則,如IPPROTO_TCP,IPPROTO_UDP等。更多描述man 2 socket。

socket()通過調用sys_socket系統調用為我們建立了socket資料結構,該結構維護著主機或進程間進行資料傳遞操作需要的參數;對編程重要的成員有【1】網路檔案系統sockfs的i-node,由kernel建立;通過返回的file descriptor 檔案描述符關聯,我們可以對這個Socket進行操作:read、write。【2】本地主機的IP地址,由參數domain指定具體格式,由bind()系統調用初始化為具體的值。【3】Socket類型,由參數type初始化。【4】資料轉送協議,由參數protocol指定。【5】地址族,有domain指定。

通用Socket地址結構——struct sockaddr

因為不同的domain域決定了不同Socket的地址格式,而系統調用又要為所有的應用提供一致,統一的Interface,這就產生了矛盾;所以通過使用通用地址結構消除不同的Socket地址結構對系統調用的影響,使系統調用不特定於某一個地址結構。你想用這些系統調用,好啊,先轉化成我規定的通用結構struct sockaddr * 吧~~你可能會說,我通過void *指標也能實現呀何必再定義一個結構呢,但是,在1982年那會兒,ANSI C 的 void * 還沒出生~~

Byte order位元組序

你需要記住:Big endian大端、Network byte order網路位元組序、人書寫和識別多位元組類型的變數,他們三個順序是一致的:都是最高有效位的位元組在最初的地方,即最低地址,自己體會吧~~剩下的就是Linux的Little endian了~POSIX規定我們的TCP或UDP分組 的協議頭部中目標主機地址和本機地址,統一使用大端網路位元組序的儲存方式~~同樣地址結構中標識進程的連接埠port也應轉為網路位元組序使得TCP協議棧正確識別。淺談位元組序(Byte Order)及其相關操作 那麼,我們要通過網路在可能位元組序不一致的OS系統傳輸位元據呢?有兩種解決辦法【1】轉化為字串文字格式設定【2】顯示對傳輸資料的位元組序進行說明。需要注意,因為文本中的字元是不存在這種位元組序問題的:ASCII是單位元組編排每個字元的,自然不會出現多個位元組間的位元組序問題;而像UTF-8,UTF-16這樣的字元編碼集中有一位用來顯示指定資料使用的位元組序~~~

為什麼connect()失敗後就不能再重連呢?這真的是個問題,有待解決。

Google的結果是connect()失敗後Socket的狀態是未知的,再次connect()可能產生錯誤結果,需close後重建Socket重連~~不成功則成仁,硬,夠硬!硬不硬以後再說~~

什麼是TCP連接埠/UDP連接埠?

Port連接埠在TCP/IP協議棧上,可以看成一個資料結構和一個緩衝區。它用來標明一種服務類型只要你的應用提供這種服務,你就可以和Kernel申請佔用這個Port(調用bind()系統調用);比如大家最熟悉的服務是web網頁瀏覽服務,對應的Port連接埠號碼是80,像Tomcat和Apache這樣的Web 應用程式伺服器配置軟體都可以佔用這個連接埠;請記住【1】一個Port連接埠在同一時間只能被一個應用(進程或線程)監聽。在Unix(BSD)上可以設定SO_REUSEPORT這個Socket設定選項使多個Process進程或線程 ,同時監聽同一個Port連接埠,但是這會引發混亂問題:TCP/IP協議棧不能正確的識別並傳送資料給正確的進程;為了消除這個問題Linux上不支援SO_REUSEPORT這個Socket 選型,我在Ubuntu10.10上沒有這個常量的定義;【2】父子進程或多個線程之間同時可以使用 同一個Port來標註不同的進程或線程,而不會出現混亂:原因是Socket通訊的兩個進程或線程是通過Socket地址對(唯一的!)進行標識的。對於第二點UNPv2 2.9和2.10節有精彩的論述,貼一張UNPv2的原圖協助理解,實在不能理解看那就看UNPv2吧:

 

UNIX Domain Socket

講檔案系統的路徑名Bind 到Unix domain Socket 作為地址時,請注意:

 

【1】不能將已經存在的檔案路徑名bind到Unix domain Socket【2】為了不打麻煩,最好bind絕對檔案路徑名,你們懂的~【3】bind的檔案路徑名和Socket是Injective function一一映射的 【4】open()不能用於Unix domain Socket【5】在操作結束後,應該顯示的調用unlink() or remove()刪除建立的檔案。

The Linux Abstract Socket Namespace【LASN】——linux虛擬Socket命名空間

LASN提供了一種新的機制來建立UNIX Domain Socket 的地址,先來說說LASN的有點【1】不用擔心建立的檔案存在的問題~【2】不需要顯示的刪除建立的檔案,當Socket關閉時這個名字自動被刪除~【3】不方便讀寫檔案系統時,也可以使用Unix域Socket~~使用起來非常簡單,就是在檔案的正式名字前加上一個NULL,其他的不變,這是TLPI的代碼:

struct sockaddr_un addr;<br />memset(&addr, 0, sizeof(struct sockaddr_un)); /* Clear address structure */<br />addr.sun_family = AF_UNIX; /* UNIX domain address */<br />/* addr.sun_path[0] has already been set to 0 by memset() */<br />strncpy(&addr.sun_path[1], "xyz", sizeof(addr.sun_path) - 2);<br />/* Abstract name is "xyz" followed by null bytes */<br />sockfd = socket(AF_UNIX, SOCK_STREAM, 0);<br />if (sockfd == -1)<br /> errExit("socket");<br />if (bind(sockfd, (struct sockaddr *) &addr,sizeof(struct sockaddr_un)) == -1)<br /> errExit("bind");

 

 

 


Internet Domain Socket

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.