Linux _ socket 文件系統套接字

套接字(socket)服務器

  1. 什麼是套接字
    套接字是一種通訊機制
    經過套接字,可實現本機內的通訊、也能夠實現跨網絡的通訊。markdown

  2. 使用套接字實現本地通訊(本機內的服務器和客戶端)
    實例:server1.c
    client1.c網絡

  3. 文件系統套接字服務器客戶端開發步驟
    文件系統套接字,用於本機內通訊
    1) 服務器端
    (1) 刪除之前的文件系統套接字所對應的文件
    (2) 建立一個文件系統套接字
    (3) 設置服務器地址
    (4) 綁定該套接字,使得該套接字和對應的系統套接字文件關聯起來。
    (5) 建立套接字隊列, 保存進入該服務器的客戶端請求
    (6) 循環處理客戶端請求
    使用accept等待並接收客戶端請求
    收到客戶端請求後,accept返回一個新的socket(表示該客戶端鏈接)
    使用這個新的socket,對客戶端進行「讀寫「
    處理完畢後,關閉這個新的socketdom

    2) 客戶端
    (1) 建立一個套接字
    (2) 設置服務器地址
    (3) 使用該socket和服務器地址鏈接服務器(connect)
    (4) 使用該socket發送和接受數據。
    (5) 關閉該socketsocket

  4. 相關係統調用
    1)建立套接字
    socket
    原型:int socket(int domain, int type, int protocol);
    參數:domain, 表示套接字的域,至關於套接字的類型
    經常使用的域有:AF_UNIX , 文件系統套接字,用於在本機的文件系統內通訊
    AF_INET, UNIX網絡套接字,用於網路通訊。
    type, 表示該套接字的特性
    文件系統套接字,通常使用SOCK_STREAM
    UNIX網絡套接字,可以使用:
    SOCK_STREAM, 使用TCP通訊
    SOCK_DGRAM, 使用UDP通訊spa

    補充:SOCK_STREAM, 是有序、可靠、面向鏈接的通訊, 對於UNIX網絡套接字,經過TCP實現
                             SOCK_DGRAM, 即數據報服務,不保證按序到達, 對於UNIX網絡套接字,經過UDP實現
    
            protocol,具體使用的協議。
                          通常取0,即表示使用默認的協議。

    2) 套接字地址
    文件系統套接字的地址:code

struct  sockaddr_un {
                sa_family_t    sun_family;                    //即取AF_UNIX
                char              sun_path[UNIX_PATH_MAX];    //路徑名
         }
UNIX網絡套接字:
struct sockaddr_in  {
                short  int                  sin_family;        //取 AF_INET
                unsigned short  int    sin_port;           //端口號
                struct in_addr           sin_addr;          // ip地址 
         }
補充:
struct  in_addr {
                unsigned long int  s_addr;   //4字節的IP地址
                                                         //例:addr.s_addr = inet_addr("192.168.168.110")
         }
注意:相關的系統調用中,使用的地址又是struct sockaddr類型,
              因此須要進行類型轉換,不然將出現警告。

2)綁定套接字
     對於文件系統套接字,綁定該套接字後,
          使得該套接字和對應的系統套接字文件關聯起來

     對於UNIX網絡套接字,綁定該套接字後,使得該套接字和一個端口號關聯起來

     bind 
     原型:int  bind (int sockfd,   const struct sockaddr *my_addr,    socklen_t addrlen);
     返回值:成功,返回0
                失敗,返回-1

     注意:綁定文件系統套接字時,地址中sun_path若是不指定絕對路徑,則表示使用當前路徑。
             若是在當前路徑無相關權限,則可能致使bind失敗。
             解決辦法:指定一個具備權限的路徑便可,好比/tmp/...

3) 建立套接字隊列
    listen
    原型:int  listen (int sockfd,   int backlog);
    功能: 建立一個隊列,用來保存訪問該服務器套接字的請求。
            參數2表示同時最多能接受多少個客戶端 請求,通常取5,即該隊列中最多可排5個請求。
    返回值:成功,返回0
               失敗, 返回-1

4)接受客戶端請求
     accept
     原型:int  accept(int sockfd,  struct sockaddr *addr,   socklen_t *addrlen);
     功能:等待並接受客戶端的請求。
              若是沒有客戶端發起請求,則阻塞。
              若是已有多個請求,則在該套接字的隊列中取出第一個請求。
      參數:sockfd,  服務器套接字。
              addr, 所接收到的客戶端地址
                         注意:若是不關心所接受的客戶端的地址,則param2和param3均可覺得0
      返回值:成功,則返回一個新的套接字,以表示與該客戶端的鏈接。
                          直接使用該套接字,就能夠對客戶端進行讀寫。
                 失敗:返回-1
      注意:參數3必需要初始化爲對應地址的長度!

5)向服務器發送鏈接請求
     connect
     原型:int  connect(int sockfd,  const struct sockaddr *serv_addr,   socklen_t  addrlen);
     參數:sockfd, 表示鏈接服務器的套接字
             serv_addr, 服務器的地址
             addrlen, 服務器地址的長度
     返回值:成功, 0
                失敗, -1

6) 關閉套接字
     close(socket_fd);
     關閉對應的鏈接。

// 補充:
當客戶端關閉後,
服務器端能夠對該客戶端進行讀read,不阻塞返回0
但不能對該客戶端進行write操做,不然異常退出server

相關文章
相關標籤/搜索