c++ socket通信筆記

總的來說網絡程序是由兩個部分組成的--客戶端和服務器端.它們的建立步驟一般是:

    服務器端   socket-->bind-->listen—>accept
    客戶端      socket-->connect


在WINDOWS環境下使用SOCKET前需要初始化windows socket庫,否則socket()會返回SOCKET_ERROR(-1)


SOCKET socket(int domain, int type,int protocol)


  • domain:說明我們網絡程序所在的主機採用的通訊協族(AF_UNIX和AF_INET等). AF_UNIX只能夠用於單一的Unix系統進程間通信,而AF_INET是針對Internet的,因而可以允許在遠程主機之間通信
  • type:我們網絡程序所採用的通訊協議(SOCK_STREAM,SOCK_DGRAM等) SOCK_STREAM表明我們用的是TCP協議,這樣會提供按順序的,可靠,雙向,面向連接的比特流. SOCK_DGRAM 表明我們用的是UDP協議,這樣只會提供定長的,不可靠,無連接的通信.
  • protocol:由於我們指定了type,所以這個地方我們一般只要用0來代替就可以了 下面是from WINSOCK.H的協議定義

eg:

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

  • sockfd:是由socket調用返回的文件描述符.
  • addrlen:是sockaddr結構的長度.
  • my_addr:是一個指向sockaddr的指針. 在WINSOCK.H中有 sockaddr的定義 :

localaddr.sin_addr.s_addr = inet_addr(ipaddr);
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(portNum);
bind(s_ , (struct sockaddr*)&localaddr , sizeof(localaddr)) ;

   

     由於客戶端不需要固定的端口號,因此不必調用bind(),客戶端的端口號由內核自動分配。如果服務器不調用bind(),內核會自動給服務器分配監聽端口,每次啓動服務器時端口號都不一樣,客戶端要連接服務器就會遇到麻煩。

int listen (SOCKET s, int backlog);

  • s:bind後的SOCKET文件描述符
  • backlog:設置請求排隊的最大長度.當有多個客戶端程序和服務端相連時, 使用這個表示可以介紹的排隊長度.(允許監聽多少個TCP連接)
  • listen函數將bind的文件描述符變爲監聽套接字.出錯返回-1

e.g.

listen(sListen, 3);

SOCKET accept (SOCKET s, struct sockaddr *addr,  int *addrlen);

  • s:是listen後的SOCKET文件描述符
  • addr,addrlen是用來給客戶端的程序填寫的,服務器端只要傳遞指針就可以了. bind,listen和accept是服務器端用的函數,accept調用時,服務器端的程序會一直阻塞到有一個客戶程序發出了連接. accept成功時返回最後的服務器端的文件描述符,這個時候服務器端可以向該描述符寫信息了. 失敗時返回-1

e.g.

sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);


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