通過tcp協議進行c/s模式的網路通訊
1.sockaddr_in 結構體
struct sockaddr_in;
in_addr 結構體
struct in_addr;
in_addr_t 在標頭檔案 中定義,等價於 unsigned long,長度為4個位元組。也就是說,s_addr 是乙個整數,而ip位址是乙個字串,所以需要 inet_addr() 函式進行轉換.
by the way, ntohs() 本函式將乙個16位數由網路位元組順序轉換為主機位元組順序
sockaddr 結構體的定義如下:
struct sockaddr;
這裡我們使用 sockaddr_in 結構體,然後再強制轉換為 sockaddr 型別2…在 linux 下使用 標頭檔案中 socket() 函式來建立套接字,原型為:
int socket(int pf, int type, int protocol);
pf 是「protocol family」的簡寫,也就是 ip 協議型別,常用的有pf_inet 、pf_inet6 。
af 為位址族(address family),也就是 ip 位址型別,常用的有 af_inet 和 af_inet6。af_inet 表示 ipv4 位址,例如 127.0.0.1;af_inet6 表示 ipv6 位址,例如 1030::c9b4:ff12:48aa:1a2b。pf_inet 等價於 af_inet,pf_inet6 等價於 af_inet6。
type 為資料傳輸方式/套接字型別,常用的有 sock_stream(流格式套接字/面向連線的套接字) 和 sock_dgram(資料報套接字/無連線的套接字)
protocol 表示傳輸協議,常用的有 ipproto_tcp 和 ipptoto_udp,分別表示 tcp 傳輸協議和 udp 傳輸協議。在pf和type都只有一種協議滿足條件,可以將 protocol 的值設為 0,系統會自動推演出應該使用什麼協議。如下:
int tcp_socket = socket(af_inet, sock_stream, 0); //建立tcp套接字
int udp_socket = socket(af_inet, sock_dgram, 0); //建立udp套接字
使用 socket() 函式建立套接字以後,返回值就是乙個 int 型別的檔案描述符。
posix 定義了 stdin_fileno、stdout_fileno 和 stderr_fileno 來代替 0、1、2。這三個符號常量的定義位於標頭檔案 unistd.h。3.bind() 函式的原型為:
int bind(int sock, struct sockaddr *addr, socklen_t addrlen); //linux
sock 為 socket 檔案描述符,addr 為 sockaddr 結構體變數的指標,addrlen 為 addr 變數的大小,可由 sizeof() 計算得出。4.通過 listen() 函式可以讓套接字進入被動監聽狀態,它的原型為:
int listen(int sock, int backlog); //linux
sock 為需要進入監聽狀態的套接字,backlog 為請求佇列的最大長度。
所謂被動監聽,是指當沒有客戶端請求時,套接字處於「睡眠」狀態,只有當接收到客戶端請求時,套接字才會被「喚醒」來響應請求。5.當套接字處於監聽狀態時,可以通過 accept() 函式來接收客戶端請求。它的原型為:
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen); //linux
它的引數與 listen() 和 connect() 是相同的:sock 為伺服器端套接字,addr 為 sockaddr_in 結構體變數,addrlen 為引數 addr 的長度,可由 sizeof() 求得。
**accept() 返回乙個新的套接字來和客戶端通訊,addr 儲存了客戶端的ip位址和埠號,而 sock 是伺服器端的套接字,大家注意區分。**後面和客戶端通訊時,要使用這個新生成的套接字,而不是原來伺服器端的套接字。6.從伺服器端傳送資料使用 send() 函式,它的原型為:
int send(socket sock, const char *buf, int len, int flags);
最後的 flags 引數一般設定為 0 或 null,初學者不必深究。7.在客戶端接收資料使用 recv() 函式,它的原型為:
int recv(socket sock, char *buf, int len, int flags);
#include#include#includeint main()
//進入監聽狀態,等待使用者發起請求
ret = listen(sockfd, 1024);
if (-1 == ret)
//接收客戶端請求
struct sockaddr_in clntaddr;
socklen_t clntaddr_size = sizeof(clntaddr);
newfd = accept(sockfd, (struct sockaddr*)&clntaddr, &clntaddr_size);
//接收客戶端請求傳送的資料
char szbuf[1024] = "\0";
char szreplybuf[1024] = "hello, it's server!\0";
ret = recv(newfd, szbuf, sizeof(szbuf), 0);
if (ret > 0)
//向客戶端傳送資料
ret = send(newfd, szreplybuf, strlen(szreplybuf), 0);
if (ret > 0)
//關閉套接字
close(sockfd);
close(newfd);
return 0;
}
int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen); //linux
#include#include#includeint main()
char szbuf[1024] = "\0";
char szmsg[1024] = "hi, it's client!";
//向伺服器傳送資料
ret = send(sockfd, szmsg, strlen(szmsg), 0);
if (ret > 0)
//讀取伺服器傳回的資料
ret = recv(sockfd, szbuf, sizeof(szbuf), 0);
if (ret > 0)
//關閉套接字
基於TCP協議的C S通訊
一 環境 os win10 ide visual studio 2010 二 在同一解決方案下新建兩個win32控制台應用程式,專案名分別是server和client,分別在兩個專案的原始檔下新增server.cpp和client.cpp server.cpp include include inc...
網路程式設計通過tcp協議進行聊天對話
網路程式設計 自從網際網路誕生以來,現在基本上所有的程式都是網路程式,很少有單機版的程式了。計算機網路就是把各個計算機連線到一起,讓網路中的計算機可以互相通訊。網路程式設計就是如何在程式中實現兩台計算機的通訊。網路程式設計對所有開發語言都是一樣的,python也不例外。用python進行網路程式設計...
JAVA中使用TCP協議程式設計模擬C S模式
一 程式設計的基本思想 1 構建乙個伺服器和乙個客戶端,伺服器物件使用serversocket類進行宣告,在構建的同時需要給應用程式分配埠號 客戶端物件使用socket類進行宣告,在宣告客戶端物件時需要輸入伺服器的主機名或ip位址,以及埠號。2 當連線建立之後,伺服器將要傳送的資訊輸入到i o流中,...