預備:
載入套接字型檔。
過程:
1.建立套接字(socket)。
2.將套接字繫結到乙個本地位址和埠上(bind)。
3.將套接字設為監聽模式,準備接受客戶請求(listen)。
4.等待客戶請求到來;當請求到來後,接受連線請求,返回乙個新對應於此次連線的套接字(accept)。
5.用返回的套接字和客戶端進行通訊(send/recv)。
6.返回等待另一客戶請求。
7.關閉套接字。
實現:
//載入套接字型檔
#include
#include
還需要新增鏈結庫ws2_32.lib(工程=設定=鏈結=物件/庫模組)
word wversionrequested; //準備載入winsock庫的版本,注意高位元組是副版本號
wsadata wsadata; //是乙個返回值,指向wsadata結構的指標,wsastartup函式將其載入的庫版本資訊輸入到這個結構體中。
int err;
wversionrequested = makeword(1,1);
err = wsastartup(wversionrequested,&wsadata);
if(0 != err)
if(lobyte(wsadata.wversion) != 1 || hibyte(wsadata.wversion) != 1)
//跟著步驟實現套接字
1.create socket!
socket(int af,int type,int protocol); //socket 函式三個引數af,指定位址族,對於tcp/ip協議套接字,它只能是af_inet;type引數指定socket型別,對於1.1版本的socket,它只支援兩種型別的套接字,sock_stream指定產生流失套接字,sock_dgram產生資料報套接字;protocol是與特定的位址家族相關的協議,如果指定為0,那麼系統就會根據位址格式和套接字類別,自動選擇乙個合適的協議。
socket socksrv = socket(af_inet,sock_stream,0);
2.bind socket to a port!
sockaddr_in addrsrv;
addrsrv.sin_addr.s_un.s_addr=htonl(inaddr_any);
addrsrv.sin_family=af_inet;
addrsrv.sin_port=htons(6000);
bind(socksrv,(sockaddr*)&addrsrv,sizeof(sockaddr));
int bind(socket s,const struct sockaddr far *name,int namelen);
//s為指定要繫結的套接字;name指定了該套接字的本地位址資訊,這是乙個指向sockaddr結構的指標變數,該位址結構是為所有的位址家族準備的,這個結構可能隨時用的網路協議不同而不同,所以才需要第三個引數namelen指定該位址結構的長度。
sockaddr結構的定義如下:
struct sockaddr;
其中sa_family指定位址家族,對於tcp/ip協議的套接字,必須設定為af_inet,sa_data[14]只是乙個佔位的作用,該區域中指定與協議相關的具體位址資訊。由於實際要求只是記憶體區,所以對不同的協議家族,用不同的結構來替換sockaddr。除了sa_family外,sockadd是按網路位元組順序表示的。在基於tcp/ip的socket程式設計中,可以使用sockaddr_in結構替換sockaddr,以方便我們填寫位址資訊。
struct sockaddr_in;
sockaddr_in和sockaddr的長度是一樣的。
需要注意的是sin_addr的型別是in_addr,而in_addr實際上是乙個聯合
struct in_addrs_un_b;
structs_un_w;
u_long s_addr;
}s_un;
};所以才有了上面的 addrsrv.sin_addr.s_un.s_addr=htonl(inaddr_any);
inaddr_any,表示的是所有ip!
3.將套接字設為監聽模式
listen(socksrv,5);
// int listen(socket s,int backlog); s是socket不用說,backlog是等待佇列的最大長度,比如現在設為2,那麼假如同時有3個請求來到伺服器端的時候,就把前兩個放到請求佇列中,第三個就會被拒絕。
4.等待客戶請求到來,返回連線套接字和通訊
sockaddr_in addrclient;
int len=sizeof(sockaddr);
while(1)
//accept();這個函式是用來接受客戶端傳送的連線請求。並返回建立連線的socket:
socket accept(
socket s,
struct sockaddr far* addr,
int far* adrlen
);s表示已經通過listen函式設為監聽狀態的socket!addr是指向緩衝區的指標,儲存發起連線的這個客戶端的ip位址資訊和埠資訊;addrlen是addr的長度。
//send函式通過乙個已經建立連線的套接字傳送資料,recv是通過乙個已經建立連線的套接字接收資料。兩個函式的引數基本一樣。
int send(socket s,const char far* buf,int len,int flags);
不同的只有buf,對於send那是傳送資料的buf,而對於recv那是接收資料的buf,flags通常情況下為0.
注意上面用了乙個函式inet_ntoa是格式化ip位址的,將接受乙個ulong型的資料返回乙個被格式化成了點分的字串的ip(如:192.168.0.1),還有乙個inet_addr作用和inet_ntoa正好相反。
VC中的socket程式設計
基於tcp的socket程式設計 伺服器端程式 1 建立socket 2 將套接字繫結到乙個本地位址和埠上 bind 3 將套接字設為監聽模式,準備接受客戶請求 listen 4 等待客戶請求到來 當請求到來後,結合搜此次連線的套接字 accept 5 用返回的套接字和客戶端進行通訊 send re...
VC下socket網路程式設計實現
sockets 套接字 程式設計有三種,流式套接字 sock stream 資料報套接字 sock dgram 原始套接字 sock raw 基於tcp的socket程式設計是採用的流式套接字。在這個程式中,將兩個工程新增到乙個工作區。要鏈結乙個ws2 32.lib的庫檔案。伺服器端程式設計的步驟 ...
VC 中Socket程式設計的實現 UDP客戶端
預備 載入套接字型檔 include include 還需要新增鏈結庫ws2 32.lib 工程 設定 鏈結 物件 庫模組 word wversionrequested 準備載入winsock庫的版本,注意高位元組是副版本號 wsadata wsadata 是乙個返回值,指向wsadata結構的指標...