Win32 客戶端程式

2021-06-14 11:28:16 字數 4689 閱讀 6707

乙個socket客戶端程式的典型過程如下。

客戶端程式在執行後,首先需要使呼叫wsastartup函式,確保程序載入socket應用程式所必須的環境和庫檔案,如ws2_32.dll。

呼叫函式socket建立socket,在建立時需指定使用的網路協議、連線型別等。

填充sockaddr結構,指定服務端的位址、埠等。

呼叫connect函式連線到服務端。

如果連線成功,就可以使用send和recv函式傳送和接收資料。

在資料傳輸完成後,可呼叫closesocket函式關閉socket。

呼叫wsacleanup函式釋放資源。

新建win32專案控制台程式 win32client專案:

// win32client.cpp : 定義控制台應用程式的入口點。 

#include "stdafx.h"

#include #include #pragma comment(lib,"wsock32.lib")

#define defip "127.0.0.1" //本地位址

#define defport 10000 //埠要大於1024

void main()

socket sockfd=socket(af_inet,sock_stream,ipproto_tcp);

if (sockfd == invalid_socket)

// sockaddr_in clientaddr;

// clientaddr.sin_family=af_inet;

// clientaddr.sin_addr.s_addr= inet_addr("192.168.1.102");

// clientaddr.sin_port=htons(12345); //伺服器會獲取此埠

// if(bind(sockfd,(sockaddr*)&clientaddr,sizeof(clientaddr)) == socket_error)

//

sockaddr_in serveraddr;

serveraddr.sin_family=af_inet;

serveraddr.sin_addr.s_addr= inet_addr(defip);

serveraddr.sin_port=htons(defport);

if(connect(sockfd,(sockaddr*)&serveraddr,sizeof(sockaddr)) == socket_error)

int bytessend=0;

char sendbuf[32]="get information";

bytessend=send(sockfd,sendbuf,strlen(sendbuf)+1,0);

if (bytessend == socket_error)

printf("bytes send: %ld\n",bytessend);

int bytesrecv=0;

char recvbub[2096]=;

while( bytesrecv != socket_error)

printf("bytes recv:[%d] %s\n",bytesrecv,recvbub);

} closesocket(sockfd);

wsacleanup();

}

/*

wsastartup():功能是載入ws2_32.dll等socket程式執行的環境。在程式初始化後,socket程式執行所依賴的動態鏈結庫不一定已經載入,wsastartup保證了socket動態鏈結庫的載入。

int wsastartup(_in word wversionrequested,_out lpwsdata lpwsadata);

wversionrequested:是socket程式庫的版本,一般使用makeword(2,2)巨集

lpwsadata:輸出引數,指向wsadata結構的指標,用於返回scoket庫初始化的資訊

返回值:0表示成功,

wsacleanup():與wsastartup()的功能相反,wsacleanup釋放ws2_32.dll庫。

socket socket( int af, int type, int protocol );

引數:int af:通訊協議族(af_unix,af_inet等),af_unix只能夠用於單一的unix系統程序間的通訊,而af_inet是針對internet的,因此可以允許遠端——本機之間的通訊。af:address families(位址協議族)。協議族決定了socket的位址型別,在通訊中必須採用對應的位址,如af_inet決定了要用ipv4位址(32位的)與埠號(16位的)的組合、af_unix決定了要用乙個絕對路徑名作為位址。

int type:socket型別:sock_stream(tcp/ip),sock_dgram(udp)

int protocol:指定協議(有ipproto_tcp、ipptoto_udp、ipproto_sctp、ipproto_tipc等,它們分別對應tcp傳輸協議、udp傳輸協議、stcp傳輸協議、tipc傳輸協議),由於我們指定了type,所以這個地方我們一般只要用0來代替就可以了

返回值:若成功返回socket物件標識,socket就是unsigned int;如失敗,則返回invalid_socket,呼叫wsagetlasterror()可得知原因,所有winsocket的函式都可以使用這個函式來獲取失敗的原因。

注意:並不是上面的type和protocol可以隨意組合的,如sock_stream不可以跟ipproto_udp組合。當protocol為0時,會自動選擇type型別對應的預設協議。

當我們呼叫socket建立乙個socket時,返回的socket描述字它存在於協議族(address family,af_***)空間中,但沒有乙個具體的位址。如果想要給它賦值乙個位址,就必須呼叫bind()函式,否則就當呼叫connect()、listen()時系統會自動隨機分配乙個埠。

typedef struct sockaddr_in

sockaddr_in;

struct in_addr // internet address.

;//sin_:socket address internet

struct sockaddr是通用的套接字位址,而struct sockaddr_in則是internet環境下套接字的位址形式,二者長度一樣,都是16個位元組。二者是並列結構,指向sockaddr_in結構的指標也可以指向sockaddr。一般情況下,需要把sockaddr_in結構強制轉換成sockaddr結構再傳入系統呼叫函式中。

位元組轉換函式

在網路上面有著許多態別的機器,這些機器在表示資料的位元組順序是不同的,比如i386晶元是低位元組在記憶體位址的低端,高位元組在高階,而alpha晶元卻相反.為了統一起來,則有專門的位元組轉換函式.

unsigned long int htonl(unsigned long int hostlong)

unsigned short int htons(unisgned short int hostshort)

unsigned long int ntohl(unsigned long int netlong)

unsigned short int ntohs(unsigned short int netshort)

在這四個轉換函式中,h代表host, n代表 network.s代表short l代表long

第乙個函式的意義是將本機器上的long資料轉化為網路上的long.其他幾個函式的意義也差不多

int connect(socket s,const struct sockaddr far * name,int namelen);

引數:s:socket的標識碼

name:儲存伺服器的連線資訊(協議族,伺服器的ip,埠)

namelen:name的長度

返回值:成功返回0,失敗返回socket_error

int send( socket s, const char far *buf,int len, int flags );

引數:s:socket 的識別碼

buf:存放要傳送的資料的暫存區

len buf:的長度

flags:此函式被呼叫的方式,可以設為 0或msg_dontroute及msg_oob組合

返回值:若成功則返回傳送的資料的長度,否則返回socket_error

int recv( socket s, char far *buf, int len, int flags );

引數:s:socket 的識別碼

buf:存放接收到的資料的暫存區

len buf:的長度

flags:此函式被呼叫的方式,可以設為 0或msg_dontroute及msg_oob組合

返回值:若成功則返回接收資料的長度,否則返回socket_error

int closesocket(socket s);

*/

其結果:

其bytesrecv=recv(sockfd,recvbub,strlen(recvbub)+1,0);   改為   bytesrecv=recv(sockfd,recvbub,sizeof(recvbub)+1,0);

C開發win32程式

1,先建立乙個空的win32工程,再建立乙個c 原始檔到此工程 2,編輯原始檔 include 標頭檔案宣告 int winapi winmain hinstance hinstance,hinstance hprevinstance,pstr szcmdline,int icmdshow 主函式為...

win 32 程式開發流程

windows 程式分為 程式 和 ui user inte ce 資源 兩大部份,兩部份最後以rc 編譯器集成為乙個完整的exe 檔案 圖1 1 所謂ui 資源是指功能選單 對話方塊 外貌 程式圖示 游標形狀等等東西。這些ui 資源的實際內容 二進位制 系借助各 種工具產生,並以各種副檔名存在,如...

學習win32程式步驟

不可跨越 1.c語言 2.c c是c,c 是c 很多同志學過其他語言,雖然有物件導向概念,但還是需要好好看看,c 語言還是複雜的,特別是其指標的使用,才使得其效率的保證.上面是第一階段。了解語言後就得練習,更進一步的了解語言,如看effective c 等,或者自己手動寫些 來練習,熟能生巧嘛.3....