Linux網絡編程——TCP編程基礎知識點總結

關於網絡編程的基礎知識,我再之前的博客裏面有總結,感興趣的可以看一下:網絡編程——基礎知識總結
TCP傳輸層協議(Transmission Control Protocol)是一種面向連接、可靠DE ,基於字節流的傳輸層通信協議
在七層模型中,它屬於傳輸層,建立主機到端口之間的連接。

在這裏插入圖片描述

TCP編程步驟

服務器端一般步驟

1、 創建一個socket,用函數socket();
2、 設置socket屬性,用函數setsockopt(); * 可選
3、 綁定IP地址、端口等信息到socket上,用函數bind();
4、 開啓監聽,用函數listen();
5、 接收客戶端上來的連接,用函數accept();
6、 收發數據,用函數send()和recv(),者read()和write();
7、 關閉網絡連接;
8、 關閉監聽;

客戶端一般步驟

1、 創建一個socket,用函數socket();
2、 設置socket屬性,用函數setsockopt();* 可選
3、 綁定IP地址、端口等信息到socket上,用函數bind();* 可選
4、 設置要連接的對方的IP地址和端口等屬性;
5、 連接服務器,用函數connect();
6、 收發數據,用函數send()和recv(),或者read()和write();
7、 關閉網絡連接;

socket中的函數

socket函數

int socket(int domin int type int protocol);

參數:
①domin
在這裏插入圖片描述
②type
SOCK_STREAM:流式套接字【唯一對應於TCP】
SOCK_DGRAM:數據報套接字【唯一對應着UDP】
SOCK_RAM:原始套接字
③protocol
一般填0,原始套接字編程是需填充

返回值
RETURN VALUE
on success,a file descriptor for the new socket is returned.On error,-1 is returned,and errno is set appropriately
成功時返回文件描述符,出錯時返回-1.

bind()函數

用於將socket描述符與本機上的一個端口相關聯(僅僅用於服務器)

int bind(int sockefd, const strict sockaddr*addr, sockelen_t addrlen);

參數:
sockfd:是一個socket描述符通過socket函數拿到fd
addr:struct sockaddr的結構體變量的地址
addrlen=sizeof(struct aockaddr)

struct sockaddr{
sa_family;
char sa_data(14);
}

返回值:成功=0;失敗=-1;erno=錯誤號
可以用下面的賦值自動獲取本機IP地址和隨機獲取一個沒有被佔用的端口號:
addr.sin_port=0/系統隨機選擇一個未被使用的端口號/
addr.sin_.s_addr=INADR_ANY;/填入本機IP地址/

Connect函數

與遠端服務器建立一個TCP連接 (用於客戶端)

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

Sockfd是目的服務器的sockt描述符
serv_addr是包含目的機IP地址和端口號的指針。
返回:成功=0;失敗=-1,errno=錯誤號。

listen函數

監聽是否有服務請求,用於bind()後

int listen(int sockefd, int backlog);

參數:
sockfd:通過socket()函數拿到fd
backlog:一般填5;同時允許幾路客戶端和服務器進行連接的過程,測試得知,ARM最大爲8
內核中服務器的套接字fd會維護兩個鏈表(數量=2*backlog+1)
已經建立好的連接的客戶端鏈表(已經完成3次握手飛配好了newfd)
返回值:
成功:0;出錯:1

accept函數

阻塞等待客戶端連接請求

int accept(int sockefd, struct sockaddr *addr,sockelen_t*addrlen);

參數:
scokefd:經過前面的socket(),並通過bind(),listen()設置的fd
addr:struct sockaddr的結構體變量的地址
addrlen:地址長度
返回值:
成功:返回已經建立好連接的newfd
失敗:-1

read()、write()函數

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);

read():

  • read函數是負責從fd中讀取內容

  • 當讀取成功時,read返回實際所讀的字節數

  • 如果返回的值是0表示已經讀到文件的結束,小於0則表示出現了錯誤

  • 如果錯誤爲EINTR說明是由終端引起的;如果是由ECONNREST表示網絡連接出了問題

  • write():

  • write函數將buf中的nbytes字節內容寫入文件描述符fd

  • 成功時返回寫的字節數,失敗時返回-1,並設置errno變量

  • 在網絡程序中,當我們向套接字文件描述符寫時存在兩種可能:

    • 1、write的返回值>0,表示寫了部分或者全部的數據
    • 2、返回的值<0,此時出現了錯誤
  • 如果錯誤爲EINTR表示在寫的時候出現了中斷錯誤;如果爲EPIPE表示網絡連接出現問題(對方已經關閉了連接)

Send函數

在連接(TCP)的socket方式下發送信息
int send(int sockfd, const void *msg, int len, int flags);
Sockfd是用來傳輸數據的socket描述符
msg是一個指向要發送數據的指針。
Len是以字節爲單位的數據的長度。
flags一般情況下置爲0。

recv函數

在連接(TCP)的socket方式下接收數據
int recv(int sockfd,void *buf,int len,unsigned int flags);
Sockfd是接受數據的socket描述符;
buf 是存放接收數據的緩衝區;
len是緩衝的長度。
Flags也被置爲0。
返回:實際上接收的字節數,如果連接中止,返回0,。出現錯誤時,返回-1並置相應的errno值。

sendto函數

在在無連接(UDP)的socket方式下發送數據
int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);
to表示目地機的IP地址和端口號信息
tolen=sizeof (struct sockaddr)。
返回:實際發送的數據字節長度或在出現發送錯誤時返回-1。

Recvfrom函數

在無連接(UDP)的socket方式下接收數據
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);
from 保存源機的IP地址及端口號。
fromlen=sizeof(struct sockaddr)。
返回:實際存入from中的數據字節數。當出現錯誤時返回-1,並置相應的errno。

close函數

釋放socket,停止任何數據操作
close(sockfd);

shutdown函數

單向關閉連接
int shutdown(int sockfd,int how);
how可以設爲下列值:
·0-------不允許繼續接收數據
·1-------不允許繼續發送數據
·2-------不允許繼續發送和接收數據,均爲允許則調用close ()
shutdown在操作成功時返回0,在出現錯誤時返回-1(並置相應errno)。

gethostbyname函數

域名和IP地址的轉換
struct hostent *gethostbyname(const char *name);

inet_pton函數

將點分十進制串轉換成網絡字節序二進制值,此函數對IPv4地址和IPv6地址都能處理。
int inet_pton(int family,const char * strptr,void * addrptr);
第一個參數可以是AF_INET或AF_INET6:第二個參數是一個指向點分十進制串的指針:第三個參數是一個指向轉換後的網絡字節序的二進制值的指針。
返回:1—成功0—輸入不是有效的表達格式-1—失敗

inet_ntop函數

和inet_pton函數正好相反,inet_ntop函數是將網絡字節序二進制值轉換成點分十進制串。
const char * inet_ntop(int family,const void * addrptr,char * strptr,size_t len);
第一個參數可以是AF_INET或AF_INET6:第二個參數是一個指向網絡字節序的二進制值的指針;第三個參數是一個指向轉換後的點分十進制串的指針;第四個參數是目標的大小,以免函數溢出其調用者的緩衝區。
返回:指向結果的指針—成功NULL—失敗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章