1. 程式人生 > >網路程式設計-套接字(scoket)

網路程式設計-套接字(scoket)

socket程式設計 

socket這個詞可以表示很多概念: 在TCP/IP協議中,“IP地址+TCP或UDP埠號”唯一標識網路通訊中的一個程序,“IP地址+埠號”就稱為socket。  

在TCP協議中,建立連線的兩個程序各自有一個socket來標識,那麼這兩個socket組成的socket pair就唯一標識一個連線。socket本身有“插座”的意思,因此用來描述網路連線的一 對一關 系。  TCP/IP協議最早在BSD UNIX上實現,為TCP/IP協議設計的應用層程式設計介面稱為socket API。

在網路中,必須保證資料是大端儲存。必須從低地址處傳送,資料是高位的。 TCP/IP協議規定,網路資料流應採用大端位元組序,即低地址高位元組。

socket API是一層抽象的網路程式設計介面,適用於各種底層網路協議,如IPv4、IPv6、UNIX Domain Socket。然而,各種網路協議的地址格式並不相同,如下圖所⽰示:  sockaddr資料結構  


IPv4和IPv6的地址格式定義在netinet/in.h中,IPv4地址用sockaddr_in結構體表示,包括16位埠號和32位IP地址,IPv6地址用sockaddr_in6結構體表示,包括16位埠號、128位IP地址和一些控制欄位。UNIX Domain Socket的地址格式定義在sys/un.h中,用sockaddr_un結構體表示。各種socket地址結構體的開頭都是相同的,前16位表示整個結構體的長度(並不是所有 UNIX的實現 都有長度欄位,如Linux就沒有),後16位表示地址型別。IPv4、IPv6和UNIX Domain Socket的地址型別分別定義為常數AF_INET、AF_INET6、AF_UNIX。這樣,只要取得某種sockaddr結構體的首地址,不需要知道具體是哪種型別的sockaddr結構體,就可以根據地址型別欄位確定結構體中的內容。因此,socket API可以接受各種型別的sockaddr結構體指標做引數

,例如bind、accept、connect等函式,這些函式的引數應該設計成void *型別以便接受各種型別的指標,但是sock API的實現早於ANSI C標準化,那時還沒有void *型別,因此這些函式的引數都用struct sockaddr *型別表示,在傳遞引數之前要強制型別轉換一下。

基於TCP協議的網路協議的一般流程:

建立套接字(scoket) int scoket(AF_INET,SOCK_STREAM,0)      返回值: 失敗返回-1;                     成功返回檔案描述符; 繫結套接字 int bind(listen_sock,(struct sockaddr*)&local,sizeof(local)); 返回值:               失敗返回-1; 設定套接字的狀態(監聽狀態)
 int listen(int scokfd,5); 返回值:                     失敗返回-1;
accept連結 成功就返回一個新建的scoket的描述符;
伺服器呼叫socket()、bind()、listen() 完成初始化後,呼叫accept()阻塞等待,處於監聽埠的狀 態,客戶端呼叫socket()初始化後,呼叫connect()發出SYN段並阻塞等待伺服器應答,伺服器應答一個SYN-ACK段,客戶端收到後從connect()返回,同時應答一個ACK段,伺服器收到後從 accept()返回。   資料傳輸的過程: 建立連線後,TCP協議提供全雙工的通訊服務,但是一般的客戶端/伺服器程式的流程是由客戶端主動發起請求,伺服器被動處理請求,一問一答的方式。因此,伺服器從 accept()返回後立刻呼叫read(),讀socket就像讀管道一樣,如果沒有資料到達就阻塞等待,這時客戶端呼叫write()傳送 請求給伺服器,伺服器收到後從read()返回,對客戶端的請求進行處理,在此期間客戶端呼叫read()阻塞等待伺服器的應答,伺服器呼叫write()將處理結果發回給客戶端,再次呼叫read()阻塞等待下一條請求,客戶端收到後從read()返回,傳送下一條請求,如此迴圈下去。   如果客戶端沒有更多的請求了,就呼叫close() 關閉連線,就像寫端關閉的管道一樣,伺服器的 read()返回0,這樣伺服器就知道客戶端關閉了連線,也呼叫close()關閉連線。注意,任何一方呼叫close() 後,連線的兩個傳輸方向都關閉,不能再發送資料了。如果一方呼叫shutdown() 則連線處於半關閉狀態,仍可接收對方發來的資料。 
基於TCP協議的單程序客戶端/伺服器的程式:


執行結果:
基於TCP協議的多程序客戶端/伺服器的程式:



執行結果:
基於TCP協議的多執行緒客戶端/伺服器的程式:



執行結果:
下面來看一個錯誤:
這是為什麼呢?

雖然server的應用程式終止了,但TCP協議層的連線並沒有 完全斷開,因此不能再次監聽同樣的server埠。

server的TCP連線收到client發的FIN段後處於TIME_WAIT狀 態。TCP協議規定,主動關閉連線的一方要處於TIME_WAIT狀態,等待兩個MSL(maximum segment lifetime) 的時間後才能回到CLOSED狀態,因為我們先Ctrl-C終止了server,所 以server是主動關閉連線的一方,在TIME_WAIT期間仍然不能再次監聽同樣的server端 口。MSL在RFC1122中規定為兩分鐘,但是各作業系統的實現不同,在Linux上一般經過半分鐘後 就可以再次啟動server 了。

如何解決:

使用setsockopt()設定socket描述符的選項SO_REUSEADDR為1, 表⽰允許建立埠號相同但IP地址不同的多個socket描述符。 

int opt = 1;

setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

相關推薦

網路程式設計-scoket

socket程式設計  socket這個詞可以表示很多概念: 在TCP/IP協議中,“IP地址+TCP或UDP埠號”唯一標識網路通訊中的一個程序,“IP地址+埠號”就稱為socket。   在TCP協

Java 網路程式設計 使用TCP/IP的Socket進行通訊

使用TCP/IP的套接字(Socket)進行通訊 套接字Socket的引入   為了能夠方便地開發網路應用軟體,由美國伯克利大學在Unix上推出了一種應用程式訪問通訊協議的作業系統用呼叫socket(套接字)。   socket的出現,使程式設計師可以很方便地訪問TCP/

Windows Socket-MFC程式設計

同步:指傳送方發出資料後,等收到接收方發回的響應,才發下一個數據包的通訊方式 非同步:指的是傳送方不等接收方響應,便接著發下個數據包的通訊方式; 阻塞:指呼叫某函式時,直到該函式完成操作,才返回;否則一直阻塞在該呼叫上 非阻塞:指呼叫某操作時,不管操作是否成功都立即返回,而不

:Socket 程式設計附例項

TCP/IP地址家族統一的套接字地址結構定義如下: struct sockaddr_in { short sin_family; //指定地址家族,即地址格式 unsigned short

javasocket實例

監聽 log 測試 ddr cat util print runnable 函數返回 客戶端socket 流程: 1、連接遠程主機 2、發送數據 3、接收數據 4、關閉流與socket連接 實例: import java.io.*; import jav

什麽是網絡Socket

ise 通信 function conn linux writing 深入 ket targe   什麽是網絡套接字(Socket)?一時還真不好回答,而且網絡上也有各種解釋,莫衷一是。下文將以本人所查閱到的資料來說明一下什麽是Socket。 Socket定義   Sock

網絡駭客初級之原始SOCK_RAW

原始套接字 駭客 網絡駭客初級之原始套接字(SOCK_RAW)本文用實際程序完成了MAC數據包分析,網絡數據分析,MAC地址掃描器和飛秋欺騙在這裏我把原來的入門改成了初級,因為對於原始套接字的操作確實在普通的TCP,UDP之上TCP和UDP確實涵蓋了普通的網絡應用程序,但請註意“普通”二字,要成為一名

網路程式設計網路位元組序及用udp寫客戶端和服務端聊天程式

認識IP地址 IP協議有兩個版本:IPV4和IPV6。 IPV4:IPV4版本的IP地址是4位元組無符號整數。那麼就存在IP地址資源匱乏的時候,這時可以採用兩種方法: DHCP:ip地址動態分配(應用層協議); NAT: 地址替換; 但是這兩種方法只是暫時的有I

關於sockets入門的一篇好文章

套接字程式設計(sockets 譯文) 作者:Kameswari Chebrolu (印度理工學院坎普爾分校電子工程系) 卡門斯瓦力 車布羅 背景 多路解編 ●轉變“主機到主機的資料包傳輸服務”到“程式到程式的資料交流通道” 位元組次序 ●兩類“位

一、基於linux下TCP\IP協議socket初識

在網際網路的世界中,不同的電腦之間需要進行資料交流,那麼他們就需要一個統一的規範,來確定怎麼樣進行交流。根據國際標準化組織ISO定義的標準,網路結構按照不同的功能分為7層,分別是物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層。在TCP/IP協體系中,

計算機網路——網路程式設計

IP協議有兩個版本,IPV4 和IPV6,但若每有特殊說明,預設都是指IPV4. IP地址是在IP協議中,用來標識網路中不同主機的地址。 我們光有IP地址就可以完成通訊了嘛?有了IP地址能夠把訊息傳送到對方的機器上,但還是需要有一個其他的標識來區分出,這個程式要給哪個程式進行解析。

網路程式設計(Socket)

網路預備知識學習:https://blog.csdn.net/hansionz/article/details/85224786 網路程式設計套接字 一.IP地址和埠號 1.IP地址 2.埠號 2.1 什麼是埠號

Linux__網路程式設計(UDP/TCP)

重點知識:          ·IP地址、埠號、網路位元組序的基本概念          ·socket api的基本用法          ·實現簡單的UDP客戶端/伺服器          ·實現簡單的TCP客戶端/伺服器(單鏈接版本,多程序版本,多執行緒版本)     

網路程式設計

TCP套接字----------------------------------------------SERVER————————————————————————————-------------------------------------------------CLI

網路程式設計基礎 & 基本TCP程式設計-基本函式

套接字基礎 一個通用套接字地址結構sockaddr: struct sockaddr { unsigned short sa_family; //套接字的協議簇地址型別,AF_XX char sa_data[14];//儲存

socket

       套接字(socket):Socket可以看成在兩個程式進行通訊連線中的一個端點,一個程式將一段資訊寫入Socket中,該Socket將這段資訊傳送給另外一個Socket中,使這段資訊能傳送到其他程式中。 套接字,是支援TCP/IP的網路通訊的基本操作單元,可

網路程式設計【socket】

在學習Linux系統程式設計的時候,程序間的通訊方式包括——管道、訊息佇列、共享記憶體、訊號量等方式。但是這些通訊方式都村子一定的缺陷——都是在同一個機器上的程序間的通訊。為了讓不同機器上的程序之間相互通訊,Linux網路程式設計便可解決。linux系統支援套接字介面,可以通

linux網路程式設計介面、ip、埠理解

它是網路通訊過程中端點的抽象表示,包含進行網路通訊必需的五種資訊:連線使用的協議,本地主機的IP地址,本地程序的協議埠,遠地主機的IP地址,遠地程序的協議埠。或者說,套接字,是支援TCP/IP的網路通訊的基本操作單元,可以看做是不同主機之間的程序進行雙向通訊的端點,簡單的說就是通訊的兩方的一種約定,用套接字中

socket程式設計 程式設計 (純理論,以後補一下實現程式碼

基本概念   套接字——應用層和傳輸層之間,提供應用傳輸介面 Web/RPC/中介軟體——應用層之上的網路開發 應用程式設計介面API(application programming interface) 套接字介面(socket interface)簡稱套接字,

基於socketserver模組實現併發的tcp、udp

tcp服務端:import socketserverclass MyHandler(socketserver.BaseRequestHandler): def handle(self): #通訊迴圈 while True: # print(self.cl