socket: 也稱作套接字,應用程式通常通過套接字向網路發出請求或者應答網路請求。
常用的套接字api函式:
1、socket():
函式原型為:int socket(int domain, int type, int protocol);
函式引數說明:
domain: 為建立的套接字指定協議集,例如:af_inet(表示ipv4網路協議)、af_inet6(表示ipv6)、af_unix或者af_local(表示本地套接字)。
type:sock_stream(可靠地面向流服務或流套接字)、sock_dgram(資料報文或者資料報文套接字)、sock_seqpacket(可靠的連續資料報服務)、sock_raw(在網路層之上的原始協議)。
protocol:指定實際使用的傳輸協議。最常見的就是ipproto_tcp、ipproto_sctp、ipproto_udp、ipproto_dccp。這些協議都在中有詳細說明。 如果該項為「0」的話,即根據選定的domain和type選擇使用預設協議。
返回值:如果發生錯誤,則返回-1,否則返回的是乙個代表新分配的描述符的整數。
2、bind():
函式原型為:int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen);
函式引數說明:
sockfd:表示使用bind函式的套接字描述符。
addrlen:用socklen_t欄位指定了sockaddr結構的長度。
返回值:如果發生錯誤,則返回-1,否則返回0。
3、listen():
當socket和乙個位址繫結之後,listen()函式會開始監聽可能的連線請求,但這是只能在有可靠資料流保證的時候使用,例如資料型別(sock_stream,sock_seqpacket)。
函式原型:int listen(int sockfd, int backlog);
函式引數說明:
sockfd:乙個socket的描述符。
backlog:乙個決定監聽佇列大小的整數,當有乙個請求來到時,就會進入此監聽佇列,當佇列滿後,新的連線請求就會返回錯誤。
返回值:0表示成功,-1表示錯誤。
4、accept():
當應用程式監聽來自其他主機的面對資料流的連線時,通過事件(比如unix select()系統呼叫)通知它。必須用 accept()函式初始化連線。 accept() 為每個連線創立新的套接字並從監聽佇列中移除這個連線。
函式原型:int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen)。
函式引數說明:
sockfd:監聽的套接字描述符。
返回值:返回新的套接字描述符,如果出錯就返回-1。進一步的通訊必須通過這個套接字。
5、connect():
connect()系統呼叫為乙個套接字設定引數連線,引數有檔案描述符和主機位址。
返回值: 返回-1表示出錯,0表示成功。
6、select():用於修整有如下情況的套接字列表:準備讀,準備寫或者是用錯誤。
7、poll():用於檢查套接字的狀態。套接字可以被測試,看是否可以寫入、讀取或是用錯誤。
8、getsockopt():用於查詢指定的套接字乙個特定的套接字選項的當前值。
9、setsockopt():用於為指定的套接字設定乙個特定的套接字選項。
使用tcp的伺服器:
設定乙個簡單的tcp伺服器的步驟:
1、呼叫socket函式建立套接字。
2、呼叫bind函式把套接字繫結到乙個監聽埠上。注意bind函式需要接受乙個sockaddr_in結構體作為引數,因此在呼叫bind函式之前, 程式要先宣告乙個 sockaddr_in結構體,用memset函式將其清零,然後將其中的sin_family設定為af_inet,接下來,程式需要設定其sin_port成員變數,即監聽埠。需要說明的是,sin_port中的埠號需要以網路位元組序儲存,因此需要呼叫htons函式對埠號進行轉換(函式名是"host to network short"的縮寫)。
3、呼叫listen函式,使該套接字成為乙個處在監聽狀態的套接字。
4、伺服器可以通過accept函式接受客戶端的連線請求。若沒有收到連線請求,accept函式將不會返回並阻塞程式的執行。接收到連線請求後,accept函式會為該連線返回乙個套接字描述符。accept函式可以被多次呼叫來接受不同客戶端的連線請求,而且之前的連線仍處於監聽狀態——直到其被關閉為止。
5、伺服器可以通過對send,recv或者對write,read等函式的呼叫來同客戶端進行通訊。
6、對於乙個不再需要的套接字,可以使用close函式關閉它。
**如下:
#include #include #include #include #include #include #include #include int main()
memset(&stsockaddr, 0, sizeof(struct sockaddr));
stsockaddr.sin_family = af_inet; //設定為ip通訊
stsockaddr.sin_port = htons(1200);//伺服器的埠號
stsockaddr.sin_addr.s_addr = inaddr_any;//伺服器ip位址--允許連線到所有本地位址上
//將套接字繫結到伺服器的網路位址上
if (bind(socketfd, (const struct sockaddr *)&stsockaddr, sizeof(struct sockaddr_in)) == -1)
//監聽可能的連線請求,監聽佇列長度為10
if (listen(socketfd, 10) == -1)
while (true)
//呼叫shutdown只是進行了tcp斷開,並沒有釋放檔案描述符
shutdown(connectfd, shut_rdwr);
close(connectfd);
} close(socketfd);
return 0;
}
使用tcp的客戶端:
建立乙個客戶機的步驟如下:
1、呼叫socket()建立套接字。
2、用connect()連線到伺服器,類似伺服器端的操作,將sin_family設為af_inet,sin_port設為伺服器的監聽埠(依然要以網路位元組序),sin_addr設為伺服器ip位址的(還是要用網路位元組序)的sockaddr_in作為引數傳入。
3、用send() 和 recv() 或者 write() 和 read()進行通訊。
4、用close()終止連線。如果呼叫fork(), 每個程序都要用close()。
**如下:
#include #include #include #include #include #include #include #include int main()
memset(&stsockaddr, 0, sizeof(struct sockaddr_in));
stsockaddr.sin_family = af_inet;
stsockaddr.sin_port = (1200);
res = inet_pton(af_inet, "192.168.1.4", &stsockaddr.sin_addr);
if (res < 0) else if (res == 0)
if (connect(socketfd, (const struct sockaddr *)&stsockaddr, sizeof(struct sockaddr_in)) == -1)
shutdown(socketfd, shut_rdwr);
close(socketfd);
return 0;
}
使用udp的伺服器:
#include #include #include #include #include #include #include #include int main()
while (true)
printf("recsize : %d\n", recsize);
sleep(1);
printf("datagram : %s\n", buffer);
} return 0;
}
使用udp的客戶端:
#include #include #include #include #include #include #include #include int main()
memset(&sa, 0, sizeof(sa));
sa.sin_family = af_inet;
//回環位址127.0.0.1
sa.sin_addr.s_addr = htonl(0x7f000001);
sa.sin_port = htons(7654);
bytes_sent = sendto(sock, buffer, buffer_length, 0, (struct sockaddr *)&sa, sizeof(struct sockaddr_in));
if (bytes_sent < 0)
close(sock);
return 0;
}
socket程式設計(學習筆記)
tcp ip協議找到目標位址,埠號標識軟體。public static void main string args throws exception 客戶端 public static void main string args 多執行緒通訊 構造執行緒,執行邏輯 thread thread 1 n...
Socket程式設計基礎學習
1 建立乙個socket物件 socket mysocket new socket addressfamily.internetwork,sockettype.stream,protocoltype.tcp addressfamily 定址型別 addressfamily.internetwork代...
Python學習 Socket程式設計
應用程式兩端通過 套接字 向網路發出請求或者應答網路請求。可以把socket理解為通訊的把手 hand 是乙個介面,封裝了大量方法 socket起源於unix,在unix一切皆檔案哲學的思想下,socket是一種 開啟 讀 寫 關閉 模式的實現,伺服器和客戶端各自維護乙個 檔案 在建立連線開啟後,可...