VC 中Socket程式設計的實現 TCP伺服器端

2021-07-25 15:39:12 字數 3226 閱讀 9879

預備:

載入套接字型檔。

過程:

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結構的指標...