天天看點

Linux網絡程式設計套接字socket的使用

網絡套接字:socket

一個檔案描述符指向一個套接字(該套接字内部由核心借助兩個緩沖區實作)
在通信過程中,套接字一定是成對出現的。      

網絡位元組序:

位元組在記憶體中存儲的順序
網絡位元組順序是TCP/IP中規定好的一種資料表示格式,它與具體的CPU類型、作業系統無關
進而保證資料在不同主機之間傳輸時能夠被正确解釋,網絡位元組順序采用大端排序方式
小端法:(PC本地存儲)高位存高位址。低位存低位址。    int a=0x12345678
大端法:(網絡存儲)      

//通過代碼檢測目前主機的位元組序

#include<stdio.h>

int main()
{
    // 共用體(Union)
    union{
        short value;    //2位元組
        char bytes[sizeof(short)];//char[2]
    }test;

    test.value=0x0102;
    if((test.bytes[0]==1)&&(test.bytes[1]==2)){
        printf("大端位元組序\n");
    }else if((test.bytes[0]==2)&&(test.bytes[1]==1)){
        printf("小端位元組序\n");
    }else{
        printf("未知\n");
    }
    return 0;
}      

含義:h - host 主機 to - 轉換成什麼 n - network 網絡位元組序 s - short轉ip

htonl——》主機——》網絡(IP) 192.168.1.11–>string–>atoj–>int–>htonl

ntohl——》網絡——》主機(IP)

轉端口

ntons——》網絡——》主機(Port)

htons——》主機——》網絡(port)

IP位址轉換函數:

int  inet_pton(int af,const char *src,void *dst);  本地位元組序(string IP)——>網絡位元組序

   af:AF_INET、AF_INET6
   src:傳入,IP位址(點分十進制)
   dst:傳出,轉換後的  網絡位元組序的  IP位址。
   傳回值:

    成功:    1
    異常:    0,說明src指向的不是一個有效的IP位址
    失敗:-1      
.
失敗:NULL      

sockaddr位址結構:

struct sockaddr_in addr;

addr.sin_family=AF_INET/AF_INET6            man 7 ip

addr.sin_port=htons(9527);
       int dst;
       inet_pton(AF_INET,"192.157.22.45",(void *)&dst);

【*】addr.sib_add.s_addr=htonl(INADDR_ANY);        取出系統中有效的任意IP位址。二進制類型

bind(fd,(struct sockaddr*)&addr,size);      

socket函數:

#include<sys/socket.h>
int socket(int domain,int type,int protocol);    建立一個套接字
    domain:AF_INET、AF_INET6、AF_UNIX
    type:SOCK_STREAM、SOCK_DGRAM
    protocol:0
   傳回值:
        成功:新套接字所對應檔案描述符
        失敗:-1      

bind函數:

#include<arpa/inet.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);    給socket綁定一個 位址結構(IP+port)
    sockfd:socket 函數傳回值
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_port=htsns(8888);
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
    addr:(struct sockaddr*)&addr
    addrlen:sizeof(addr)位址結構的大小。
       傳回值:
            成功:0
            失敗:-1      

listen函數:

int listen(int sockfd,int backlog);    設定同時與伺服器建立連接配接的上限數。(同時進行3次握手的用戶端數量)
        sockfd:socket 函數傳回值
        backlog:上限數值。最大值 128
        傳回值:
            成功:0
            失敗:-1      

accept函數:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);    阻塞等待用戶端建立連接配接,成功的話,傳回一個與用戶端成功連接配接的socket檔案描述
    sockfd:socket 函數傳回值
    addr:傳出參數。成功與伺服器建立連接配接的那個用戶端的位址結構(IP+port)
        socklen_t clit_addr_len=sizeof(addr);
    addrlen:傳入傳出。&clit_addr_len
        入:addr的大小。出:用戶端addr實際大小。
        傳回值:
            成功:能與伺服器進行資料通信的socket對應的檔案描述。
            失敗:-1,errno      

connect函數:

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);    使用現有的socket與伺服器建立連接配接
    sockfd:socket 函數傳回值
        struct sockaddr_in srv_addr;    //伺服器位址結構
        struct.sin_family=AF_INET;
        srv_addr.sin_port=9527        跟伺服器bind時設定的port完全一緻
        inet_pton(AF_INET,"伺服器的IP位址",&srv_addr.sin_addr.s_addr);
    addr:傳入參數。伺服器位址結構

    addrlen:伺服器的位址結構大小
    傳回值:
        成功:0
        失敗:-1