日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket套接字

發布時間:2023/12/15 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket套接字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Socket套接字
?? ?Socket是一個編程接口(網絡編程接口)。
?? ?作用是用來實現網絡上不同主機上的應用程序之間進行雙向通信。
?? ?套接字是一種特殊的文件描述符,也就意味著我們使用套接字實現網絡通信可以使用write/read。
?? ?
?? ?要實現互聯網通信,至少需要一對套接字,其中一個運行在客戶端(client socket),一個運行
?? ?服務器端(server socket).
?? ??? ?
?? ?Socket可以分為三類:
?? ??? ?1)?? ?流式套接字(SOCK_STRAM)
?? ??? ??? ?流式套接字用于提供面向連接、可靠的數據傳輸服務。
?? ??? ??? ?主要針對傳輸層協議為TCP協議的應用。
?? ??? ??? ?
?? ??? ?2)?? ?數據報套接字(SOCK_DGRAM)
?? ??? ??? ?數據報套接字提供一種無連接的服務(并不能保證數據傳輸的可靠性)。
?? ??? ??? ?主要針對傳輸層協議為UDP協議的應用。
?? ??? ??? ?
?? ??? ?3)?? ?原始套接字(SOCK_RAW)
?? ??? ??? ?原始套接字可以直接跳過傳輸層讀取沒有處理的IP數據包。
?? ??? ??? ?而流式套接字只能讀取TCP協議的數據,數據報套接字只能讀取UDP協議的數據。
?? ??? ??? ?因此,如果要訪問其他協議發送的數據必須要使用原始套接字。
?? ??? ??? ?
?? ?1.?? ?TCP套接字的編程流程
?? ??? ?1)?? ?TCP網絡應用程序的數據傳輸的大概過程
?? ??? ??? ?建立連接:--->加微信
?? ??? ??? ??? ?三次握手
?? ??? ??? ??? ?
?? ??? ??? ?發送/接受網絡數據:--->聊天
?? ??? ??? ??? ?write/send/sendto
?? ??? ??? ??? ?read/recv/recvfrom
?? ??? ??? ?
?? ??? ??? ?關閉連接:--->刪除好友
?? ??? ??? ??? ?四次揮手
?? ??? ??? ?
?? ??? ??? ?三次握手:
?? ??? ??? ??? ?客戶端?? ??? ??? ??? ??? ??? ??? ?服務器端
?? ??? ??? ??? ?你好,我希望和你建立連接
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?好的,我已經準備好了,可以建立連接
?? ??? ??? ??? ?好的,馬上和你連接
?? ??? ??? ??? ?連接成功
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?為什么要有三次握手的機制?
?? ??? ??? ??? ?通信雙方成功通信的前提條件是雙方要能夠建立連接。
?? ??? ??? ??? ?那么雙方能夠成功建立連接的前提條件又是什么呢?
?? ??? ??? ??? ?必須雙方都能夠收和發。
?? ??? ??? ??? ?所以三次握手實際上就是一個測試能不能夠建立連接的過程。
?? ??? ??? ??? ?
?? ??? ??? ?三次握手的具體過程:
?? ??? ??? ??? ?1)?? ?序號:Seq(Sequence Number)
?? ??? ??? ??? ??? ?序號占32bits,用來標識從計算機A發送到計算機B的數據包的序號
?? ??? ??? ??? ??? ?計算機發送數據時需要對此進行標記。
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?2)?? ?確認號(ACK:Acknowledge Number)
?? ??? ??? ??? ??? ?確認號也是占32bits,客戶端和服務器都可以發送,Ack = Seq + 1
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?3)?? ?標志位
?? ??? ??? ??? ??? ?每一個標志位占用一個bits,共有6個標志位。
?? ??? ??? ??? ??? ?分別是URG,ACK,PSH,RST,SYN,FIN,具體的含義如下:
?? ??? ??? ??? ??? ??? ?ACK:確認序號有效
?? ??? ??? ??? ??? ??? ?RST:重置連接
?? ??? ??? ??? ??? ??? ?SYN:建立一個新連接(synchronous)
?? ??? ??? ??? ??? ??? ?FIN:斷開一個連接(finish)
?? ??? ??? ??? ??? ??? ?
?? ??? ??? ?四次揮手:
?? ??? ??? ??? ?我們建立連接是需要消耗掉一些資源的,同樣的,我們在斷開連接的時候
?? ??? ??? ??? ?必須去釋放掉資源。
?? ??? ??? ??? ?
?? ??? ??? ?情景模擬:
?? ??? ??? ??? ?客戶端?? ??? ??? ??? ??? ??? ??? ??? ??? ?服務器端
?? ??? ??? ??? ?我發送完了,我想斷開連接
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?ok,我知道了,稍等一下,我要準備一下
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?過一會兒之后
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?好的,我已經處理完了,可以斷開連接了
?? ??? ??? ??? ?OK,拜拜,下次見
?? ??? ??? ??? ?成功斷開連接
?? ??? ??? ??? ?
?? ??? ??? ?具體的過程:
?? ??? ??? ??? ?請見圖<四次揮手原理機制>
?? ??? ??? ??? ?
?? ??? ?2)?? ?TCP編程的流程
?? ??? ??? ?TCP Server
?? ??? ??? ??? ?socket:創建套接字
?? ??? ??? ??? ?bind:把一個套接字和網絡地址綁定在一起
?? ??? ??? ??? ??? ?如果你想讓其他人來主動連接你或者聯系你,
?? ??? ??? ??? ??? ?你就需要綁定一個地址,并且需要把這個地址告訴要連接你的人
?? ??? ??? ??? ?listen:讓套接字進行監聽模式
?? ??? ??? ??? ?accept:接受客戶端的連接?
?? ??? ??? ??? ??? ?多次調用accept就可以與不同的客戶端建立連接。
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?write/send/sendto or read/recv/recvfrom
?? ??? ??? ??? ?
?? ??? ??? ??? ?close/shutdown:“四次揮手”
?? ??? ??? ??? ?
?? ??? ??? ?TCP Client:
?? ??? ??? ??? ?socket
?? ??? ??? ??? ?bind:可綁定可不綁定
?? ??? ??? ??? ?connect:主動與TCP server建立連接--->“三次握手”
?? ??? ??? ??? ?
?? ??? ??? ??? ?write/send/sendto or read/recv/recvfrom
?? ??? ??? ??? ?
?? ??? ??? ??? ?close/shutdown:“四次揮手”
?? ??? ??? ??? ?
?? ?2.?? ?socket具體的API函數
?? ??? ?1)?? ?socket : 創建一個套接字
?? ??? ??? ?int socket(int domain,int type,int protocol);
?? ??? ??? ??? ?domain:指定域或者協議域。
?? ??? ??? ??? ??? ?socket接口不僅僅只局限于TCP/IP,它也可以用于Bluetooth,本地通信。。
?? ??? ??? ??? ??? ?那么每一種網絡通信下面都有自己的許多協議,我們就把IPv4下面的所有的
?? ??? ??? ??? ??? ?網絡協議,歸到了一個域:
?? ??? ??? ??? ??? ??? ?AF_INET : IPv4協議族
?? ??? ??? ??? ??? ??? ?AF_INET6 :IPv6協議族
?? ??? ??? ??? ??? ??? ?AF_BULETOOTH
?? ??? ??? ??? ??? ??? ?AF_UNIX/AF_LOCAL:Unix域協議族
?? ??? ??? ??? ??? ??? ?
?? ??? ??? ??? ?type:指定要創建的套接字的類型
?? ??? ??? ??? ??? ?SOCK_STRAM : 流式套接字 ---> TCP
?? ??? ??? ??? ??? ?SOCK_DGRAM : 數據報套接字 ---> UDP
?? ??? ??? ??? ??? ?SOCK_RAW : 原始套接字
?? ??? ??? ??? ?
?? ??? ??? ??? ?protocol:指定具體的應用層的協議,可以指定為0(不知名的私有應用協議)
?? ??? ??? ??? ?
?? ??? ??? ??? ?返回值:成功返回一個套接字的描述符(> 0,文件描述符)
?? ??? ??? ??? ??? ?失敗返回-1,同時errno被設置。
?? ??? ??? ??? ??? ?
?? ??? ?2)?? ?網絡地址結構體
?? ??? ??? ?socket接口它不僅僅可以用于以太網(IPv4),也可以用于IPv6,同時也可以用于bluetooth
?? ??? ??? ?,不同的協議族,他們的地址是不一樣的。
?? ??? ??? ?
?? ??? ??? ?但是我們在所有的socket進行網絡編程時,必須要指定對方的網絡地址,所以
?? ??? ??? ?我們需要有一個統一的標準對這些地址進行一個描述。
?? ??? ?
?? ??? ??? ?struct sockaddr
?? ??? ??? ?{
?? ??? ??? ??? ?sa_family_t sa_family;//指定協議(地址)族
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//sa_family_t--->unsigned short
?? ??? ??? ??? ?char sa_data[14];//包含套接字中的目標地址和端口信息
?? ??? ??? ?};
?? ??? ??? ?缺陷:IP地址和端口號混在一起保存在sa_data這個數組中的。
?? ??? ??? ?
?? ??? ??? ?struct sockaddr_in
?? ??? ??? ?{
?? ??? ??? ??? ?sa_family_t sa_family;//指定協議(地址)族
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?//sa_family_t--->unsigned short
?? ??? ??? ??? ?u_int16_t sin_port;//端口號
?? ??? ??? ??? ?struct in_addr sin_addr;//IP地址
?? ??? ??? ??? ?char sin_zero[8];//填充8個字節,無實際意義的,只是為了和其他協議族的地址
?? ??? ??? ??? ??? ??? ??? ??? ??? ?//結構體大小一樣
?? ??? ??? ?};
?? ??? ??? ?typedef uint32_t in_addr_t;
?? ??? ??? ?struct in_addr
?? ??? ??? ?{
?? ??? ??? ??? ?in_addr_t s_addr;
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?這個結構體將端口號和IP地址分開保存的。
?? ??? ??? ?
?? ??? ??? ?如:
?? ??? ??? ?struct sockaddr_in local;
?? ??? ??? ?local.sin_family = AF_INET;
?? ??? ??? ?local.sin_addr.s_addr = "192.168.31.30";//error
?? ??? ??? ?
?? ??? ?3)?? ?IP地址轉換函數
?? ??? ??? ?IP地址是以點分十進制的形式存在的。
?? ??? ??? ?
?? ??? ??? ?函數將點分十進制形式存在IP地址轉換為in_addr_t類型
?? ??? ??? ??? ?
?? ??? ??? ?#include <sys/socket.h>
?? ??? ??? ?#include <netinet/in.h>
?? ??? ??? ?#include <arpa/inet.h>

?? ??? ??? ?a:addr 點分十進制字符串
?? ??? ??? ?n:network 網絡地址
?? ??? ??? ?aton:將點分十進制字符串IP地址---> struct in_addr
?? ??? ??? ?
?? ??? ??? ?int inet_aton(const char *cp, struct in_addr *inp);
?? ??? ??? ??? ?cp:指向要轉換的點分十進制IP地址字符串
?? ??? ??? ??? ??? ?如:"192.168.31.30"
?? ??? ??? ??? ?inp:指向一個IP的地址結構體
?? ??? ??? ??? ??? ?用來保存轉換后的IP地址(32bits的數)。

?? ??? ??? ?in_addr_t inet_addr(const char *cp);
?? ??? ??? ??? ?inet_addr把cp指向的“點分十進制形式的IP字符串”轉換成IP的網絡地址結構體in_addr_t

?? ??? ??? ?in_addr_t inet_network(const char *cp);
?? ??? ??? ??? ?功能與inet_addr類似

?? ??? ??? ?char *inet_ntoa(struct in_addr in);
?? ??? ??? ??? ?把IP結構體struct in_addr轉換成一個點分十進制的IP字符串
?? ??? ??? ??? ?
?? ??? ??? ?例子:
?? ??? ??? ??? ?struct sockaddr_in local;
?? ??? ??? ??? ?local.sin_family = AF_INET;
?? ??? ??? ??? ?local.sin_addr.s_addr = "192.168.31.30";//error
?? ??? ??? ??? ?local.sin_addr.s_addr = inet_addr("192.168.31.30");
?? ??? ??? ??? ?inet_aton("192.168.31.30",&local.sin_addr);
?? ??? ??? ??? ?local.sin_port = 7878;//error
?? ??? ??? ??? ?
?? ??? ?4)?? ?整數在主機字節序與網絡字節序之間的轉換函數
?? ??? ??? ?#include <arpa/inet.h>
?? ??? ??? ?
?? ??? ??? ?h:host ?? ?n:network
?? ??? ??? ?l:long ?? ?s:short

?? ??? ??? ?uint32_t htonl(uint32_t hostlong);
?? ??? ??? ??? ?把一個32bits的整數的主機字節序轉換成網絡字節序

?? ??? ??? ?uint16_t htons(uint16_t hostshort);
?? ??? ??? ??? ?把一個16bits的整數的主機字節序轉換成網絡字節序

?? ??? ??? ?uint32_t ntohl(uint32_t netlong);
?? ??? ??? ??? ?把一個32bits的整數的網絡字節序轉換成主機字節序

?? ??? ??? ?uint16_t ntohs(uint16_t netshort);
?? ??? ??? ??? ?把一個16bits的整數的網絡字節序轉換成主機字節序

?? ??? ??? ??? ?struct sockaddr_in local;
?? ??? ??? ??? ?local.sin_family = AF_INET;
?? ??? ??? ??? ?local.sin_addr.s_addr = "192.168.31.30";//error
?? ??? ??? ??? ?local.sin_addr.s_addr = inet_addr("192.168.31.30");
?? ??? ??? ??? ?inet_aton("192.168.31.30",&local.sin_addr);
?? ??? ??? ??? ?local.sin_port = 7878;//error?? ??? ?
?? ??? ??? ??? ?local.sin_port = htons(7878);//error?? ??? ?
?? ??? ??? ?
?? ??? ?5)?? ?bind:把一個IPv4的網絡地址綁定到一個socket上面去
?? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */
?? ??? ??? ?#include <sys/socket.h>

?? ??? ??? ?int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
?? ??? ??? ??? ?sockfd:要綁定地址的套接字的描述符
?? ??? ??? ??? ?addr:通用網絡地址結構的指針
?? ??? ??? ??? ?addrlen:指定第二個實參指向的地址結構體的長度
?? ??? ??? ?
?? ??? ??? ??? ?返回值:成功返回0,失敗返回-1
?? ??? ??? ??? ?
?? ??? ?6)?? ?listen:讓套接字進入監聽模式
?? ??? ??? ?NAME
?? ??? ??? ??? ?listen - listen for connections on a socket

?? ??? ??? ?SYNOPSIS
?? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */
?? ??? ??? ??? ?#include <sys/socket.h>

?? ??? ??? ??? ?int listen(int sockfd, int backlog);
?? ??? ??? ??? ??? ?sockfd:要進入監聽模式的套接字的描述符
?? ??? ??? ??? ??? ?backlog:同時能夠處理連接請求的數目
?? ??? ??? ??? ??? ??? ?比如:5,10.....
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?返回值:成功返回0,失敗返回-1,同時errno被設置。
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ?調用成功之后,套接字將會變成"監聽套接字"。
?? ??? ??? ?
?? ??? ?7)?? ?accept?? ?
?? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */
?? ??? ??? ?#include <sys/socket.h>

?? ??? ??? ?int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
?? ??? ??? ??? ?用于TCP server接收一個來自客戶端的TCP連接建立的請求。
?? ??? ??? ??? ?sockfd:一個監聽套接字
?? ??? ??? ??? ?addr:網絡地址結構體的指針,用來保存客戶端的地址信息的。
?? ??? ??? ??? ?addrlen:網絡地址結構體的長度類型的指針,
?? ??? ??? ??? ?用來保存客戶端地址結構體的長度。
?? ??? ??? ??? ?返回值:成功返回與該客戶端的連接套接字描述符,后續與該客戶端進行數據交換
?? ??? ??? ??? ?都是通過該連接套接字描述符。失敗返回-1,同時errno被設置。

?? ??? ?8)?? ?connect
?? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */
?? ??? ?#include <sys/socket.h>

?? ??? ?int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
?? ??? ??? ?sockfd:套接字的文件描述符
?? ??? ??? ?addr:對方的地址,tcp server的地址。
?? ??? ??? ?addrlen:對方的地址結構體的大小
?? ??? ??? ?返回值:成功返回0,失敗返回-1,同時errno被設置。
?? ??? ?
?? ??? ?9)?? ?往套接字上發送數據
?? ??? ??? ?write/send/sendto
?? ??? ??? ?TCP都可以使用這三個函數,而UDP只能用sendto
?? ??? ??? ?1.?? ?write
?? ??? ??? ??? ?略
?? ??? ??? ?2.?? ?send
?? ??? ??? ??? ?#include <sys/types.h>
?? ??? ??? ??? ?#include <sys/socket.h>

?? ??? ??? ??? ?ssize_t send(int sockfd, const void *buf, size_t len, int flags);
?? ??? ??? ??? ??? ?sockfd:你要往哪一個套接字上發送數據
?? ??? ??? ??? ??? ?buf:你要發送的數據的地址
?? ??? ??? ??? ??? ?len:你要發送的數據的長度
?? ??? ??? ??? ??? ?flags:一般為0.
?? ??? ??? ??? ??? ?返回值:成功返回實際發送的字節數,失敗返回-1,同時errno被設置。
?? ??? ??? ?
?? ??? ??? ?3.?? ?ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
?? ??? ??? ??? ?const struct sockaddr *dest_addr, socklen_t addrlen);
?? ??? ??? ??? ?前面四個參數與send一樣。
?? ??? ??? ??? ?dest_addr:指定接收方的地址,是一個網絡地址結構體。
?? ??? ??? ??? ??? ?如果TCP協議通信,此處你可以省略。
?? ??? ??? ?
?? ??? ??? ??? ?addrlen:
?? ??? ??? ??? ??? ?dest_addr指向的那個地址結構體的的長度
?? ??? ??? ??? ?返回值:成功返回實際發送的字節數,失敗返回-1,同時errno被設置。

?? ??? ?10)?? ?從套接字上接收數據
?? ??? ??? ?read/read/recv/recvfrom
?? ??? ??? ?1.?? ?read
?? ??? ??? ??? ?略
?? ??? ??? ??? ?read(fd,buf,sizeof(buf))
?? ??? ??? ?
?? ??? ??? ?2.?? ?recv
?? ??? ??? ??? ?ssize_t recv(int sockfd, void *buf, size_t len, int flags);
?? ??? ??? ??? ??? ?recv前面的三個參數與read類似。
?? ??? ??? ??? ??? ?flags:一般為0。
?? ??? ??? ??? ??? ?返回值:成功返回讀取到的字節的個數,失敗返回-1,同時errno被設置。
?? ??? ??? ??? ?
?? ??? ??? ??? ?ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
? ? ? ? ? ? ? ? ? ? ? ? struct sockaddr *src_addr, socklen_t *addrlen);

?? ??? ??? ??? ??? ?src_addr:用來保存發送發的地址

?? ??? ??? ??? ??? ?addrlen:用來保存發送者地址結構體信息的長度
?? ??? ??? ??? ??? ?
?? ??? ??? ??? ??? ?返回值:成功返回實際接收到的字節數,失敗返回-1.同時errno被設置。
?? ??? ??? ??? ??? ?
?? ??? ?11)?? ?關閉套接字(close/shutdown)
?? ??? ??? ?#include <sys/socket.h>

?? ??? ??? ?int shutdown(int sockfd, int how);
?? ??? ??? ??? ?sockfd:要關閉的套接字的文件描述符
?? ??? ??? ??? ?how:關閉方式,有以下三種:
?? ??? ??? ??? ??? ?SHUT_RD:關閉讀
?? ??? ??? ??? ??? ?SHUT_WR:關閉寫
?? ??? ??? ??? ??? ?SHUT_RDWR:關閉讀寫--->close(sockfd);
?? ??? ??? ??? ?返回值:
?? ??? ??? ??? ??? ?成功返回0,失敗返回-1,同時errno被設置。

總結

以上是生活随笔為你收集整理的socket套接字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。