1. 程式人生 > >Tcp/Ip協議理解_3

Tcp/Ip協議理解_3

linux  一切皆檔案。 socket是可讀可寫可控可關閉的檔案描述符

1.建立socket

#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
  • domain 告訴系統使用哪個底層協議族   對於tcp/ip PF_INET
  • type    服務型別 SOCK_STREAM(資料流   SOCK_DGRAM(資料報
  • protocol  0 使用預設協議

2.命名socket

#include<sys/types.h>
#include<sys/socket.h>
int bind(int sockfd,const struct sockaddr*my_addr,socklen_t
addrlen);
  • bind將my_addr所指的socket地址分配給未命名的sockfd檔案描述
    符,addrlen引數指出該socket地址的長度。

  • 通常伺服器需要命名socket (只有命名後 客戶端才知道如何連線

3.監聽socket

#include<sys/socket.h>
int
listen(int sockfd,int backlog);
  • sockfd引數指定被監聽的socket
  • backlog引數提示核心監聽佇列的最大長度  (通常5(超過backlog 伺服器不受理新的客戶連線

4.接受連線

  • 從listen監聽佇列中接受一個連線
#include<sys/types.h>
#include<sys/socket.h>
int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);
  • sockfd引數是執行過listen系統呼叫的監聽socket
  • addr引數用來獲取被接受連線的遠端socket地址

  • 該socket地址的長度由addrlen引數指出

5.發起連線

  • 客戶端主動與伺服器建立連線
#include<sys/types.h>
#include<sys/socket.h>
int connect(int sockfd,const struct sockaddr*serv_addr,socklen_t
addrlen);
  • sockfd引數由socket系統呼叫返回一個socket
  • serv_addr引數是伺服器監聽的socket地址,addrlen引數則指定這個地址的長度

  • connect成功時返回0。一旦成功建立連線,sockfd就唯一地標識了
  • 這個連線,客戶端就可以通過讀寫sockfd來與伺服器通訊。connect失敗
  • 則返回-1並設定errno。其中兩種常見的errno是ECONNREFUSED和
  • ETIMEDOUT

6.關閉連線

  • 關閉一個連線實際上就是關閉該連線對應的socket
#include<unistd.h>
int close(int fd);
  • fd引數是待關閉的socket
  • 並非立即關閉 通過將fd的引用計數-1  0真正關閉

立即終止連線(不通過引用計數

  • 可以使用shutdown
#include<sys/socket.h>
int shutdown(int sockfd,int howto);
  • sockfd引數是待關閉的socket
  • howto引數決定了shutdown

 

 7.TCP資料讀寫

  • recv讀取sockfd上的資料 send 往sockfd寫資料
  • buf和len引數分別指定讀緩衝區的位置和大小
  • flags引數的含義見後文,通常設定為0即可
  • recv成功時 返回實際讀取到的資料長度

8.UDP資料讀寫

 

#include<sys/types.h>
#include<sys/socket.h>
ssize_t recvfrom(int sockfd,void*buf,size_t len,int flags,struct
sockaddr*src_addr,socklen_t*addrlen);
ssize_t sendto(int sockfd,const void*buf,size_t len,int
flags,const struct sockaddr*dest_addr,socklen_t addrlen);
  • recvfrom /sendto讀/寫sockfd上的資料
  • buf和len引數分別指定讀緩衝區的位置大小
  • 每次讀取資料都需要獲取傳送端的socket地址 src_addr 
  • addrlen引數指定該地址的長度
  • flags引數以及返回值的含義均與send/recv系統呼叫 的flags相同