[code=cpp]#include<Winsock2.h>#include<stdio.h>//需要在Project->Settings->Link->Object/librarymodules中加入ws2_32.libvoid main(){WORD wVersionRequested;WSADATA wsaData;wVersionRequested=MAKEWORD(2,2);if(WSAStartup(wVersionRequested,&wsaData)!=0)//初始化ws2_32.dll動態庫{printf("WSAStartup()failed!\n");//Winsock初始化錯誤exit(-1);}if(wsaData.wVersion!=wVersionRequested){printf("Theversion of Winsock is not suited!\n");//Winsock版本不匹配WSACleanup();//結束對ws2_32.dll的調用exit(-1);}//說明ws2_32.dll正確載入printf("Loadws2_32.dll successfully!\n");} 代碼#include<windows.h>#include<windowsx.h>#include"main.h"#include"dialogs.h"#include"resource.h"#include"winsock2.h"BOOL WINAPIMain_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ switch(uMsg) { /* BEGIN MESSAGE CRACK */ HANDLE_MSG(hWnd, WM_INITDIALOG,Main_OnInitDialog); HANDLE_MSG(hWnd, WM_COMMAND,Main_OnCommand); HANDLE_MSG(hWnd,WM_CLOSE,Main_OnClose); /* END MESSAGE CRACK */ } return FALSE;} /******************************************************************************** Main_OnInitDialog*/BOOLMain_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam){ /* Set app icons */ HICON hIcon = LoadIcon((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE) ,MAKEINTRESOURCE(IDI_ICONAPP)); SendMessage(hwnd, WM_SETICON, TRUE, (LPARAM)hIcon); SendMessage(hwnd, WM_SETICON, FALSE,(LPARAM)hIcon); /* * Add initializing code here */ return TRUE;} /******************************************************************************** Main_OnCommand*/voidMain_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify){ switch(id) { case IDC_OK: SocketTest(hwnd); break; case IDC_CANCEL: MessageBox(hwnd,TEXT("Youclicked Cancel!"),TEXT("socket"),MB_OK); EndDialog(hwnd, id); break; default:break; } } /******************************************************************************** Main_OnClose*/void Main_OnClose(HWNDhwnd){ EndDialog(hwnd, 0);} void SocketTest(HWNDhwnd){WSADATAwsaData;WSAStartup(MAKEWORD(2,0),&wsaData); //初始化socket//建立socketSOCKETsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);SOCKADDR_IN sa;sa.sin_family= AF_INET;sa.sin_port= htons(IPPORT_SMTP);sa.sin_addr.S_un.S_addr= inet_addr("123.125.50.138"); if( connect(sock, (SOCKADDR *)&sa,sizeof(sa)) == SOCKET_ERROR){ShowError();return;} char buffer[256]; ZeroMemory(buffer,sizeof(buffer)/sizeof(char)); recv(sock,buffer,256,0); MessageBox(hwnd,buffer,"",0); char sBuffer[]="QUIT\n"; send(sock,sBuffer,lstrlen(sBuffer),0); ZeroMemory(buffer,sizeof(buffer)/sizeof(char)); recv(sock,buffer,256,0); MessageBox(hwnd,buffer,"",0); closesocket(sock); WSACleanup(); } void ShowError(){ TCHAR*IpMsgBuf;FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR)&IpMsgBuf, 0, NULL ); MessageBox(NULL,IpMsgBuf,"",MB_ICONERROR); }[/code]
socket是串連運行在網路上得兩個程式間的雙向通訊的端點,在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都開啟一個Socket,並綁定到一個連接埠上,不同的連接埠對應於不同的服務。Socket正如其英文原意那樣,象一個多孔插座。一台主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電,有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。
一個完整的網路通訊需要一個五元組來標識:協議、本地地址、本地連接埠號碼、遠端地址、遠端連接埠號碼。完整的網間通訊進程需要由兩個進程組成,並且只能用同一種高層協議。也就是說,不可能通訊的一端用TCP,而另一端用UDP。
Socket通訊的兩種模式
連線導向的
連線導向的socket操作就像一部電話,他們必須建立一個串連,並由一人呼叫。所有的事情在到達時的順序與它們出發時的順序是一樣的。連線導向的操作使用TCP協議.這個模式下的socket必須在發送資料之前與目的地的socket取得一個串連.一旦串連建立了,socket就可以使用一個流介面:開啟-讀-寫-關閉.所有的發送的資訊都會在另一端以同樣的順序被接收.連線導向的操作比不需連線的操作效率低,但是資料的安全性更高.
TCP是Transfer ControlProtocol的簡稱,是一種連線導向的保證可靠的傳輸的協議。通過TCP協議傳輸,得到的是一個順序的無差錯的資料流。發送方和接受方的,成對的兩個Socket之間必須建立串連,以便在TCP協議的基礎上進行通訊,當一個Socket(通常是Serversocket)等待建立串連時,另一個socket可以要求進行串連,一旦這兩個socket串連起來,它們就可以進行雙向資料轉送,雙方都可以進行發送或操作。因為要安全可靠相對的要付出一定代價,傳輸效率不如UDP高。
不需連線的
不需連線的socket操作就像是一個郵件投遞,,沒有什麼保證,多個郵件可能在到達時的順序與出發時的順序不一樣。不需連線的操作使用資料報(UDP)協議.一個資料報是一個獨立的單元,它包含了所有的這次投遞的資訊.把它想象成一個信封吧,它有目的地址和要發送的內容這個模式下的socket不需要串連一個目的地socket,它只是簡單地投出資料報.不需連線的操作是快速的和高效的,但是資料安全性不佳.
UDP是User DatagramProtocol的簡稱,是一種不需連線的協議,每個資料報都是一個獨立的資訊,包括完整的源地址或目的地址,它在網路上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。這樣的特性決定了那些不要求音頻視頻資料絕對正確,只要保證連貫性即可的場合。
連接埠與地址
在網路上,一個Socket的標識主要藉助於地址和連接埠來描述。
地址指該通訊端所在電腦的網路地址,可以為網域名稱或IP地址的形式。同一機器上可以運行多個網路應用程式,每個應用程式都有自己的通訊端用以進行網路通訊,此時如果只有地址標識通訊端,則當一個通訊包到達機器時,將無法確定究竟是哪個應用程式的通訊端需要接收此資訊。由此增加了連接埠的概念,以協助區分同一機器上不同應用程式的通訊端
連接埠用於標識進程,同一機器上不同的網路應用程式各有不同的連接埠,這樣,通過“網路地址+連接埠號碼”的標識方法,便唯一標識了機器上的應用程式了。某些連接埠是專門為公用服務保留的(Ftp:21,http:80),除非程式是要提供這些服務,否則應盡量避免使用這些連接埠。連接埠1024以前的連接埠號碼都是系統保留的或是作為公用服務的,應盡量選擇大於1024的連接埠號碼,以避免衝突。
Socket通訊過程
1.伺服器程式將一個通訊端綁定到一個特定的連接埠,並通過此通訊端等待和監聽用戶端的串連請求。
2.客戶程式根據伺服器程式所在的主機名稱和連接埠號碼發出串連請求
3.如果一切正常,伺服器接受串連請求,並獲得一個新的綁定到不同連接埠地址的通訊端
4.用戶端和伺服器端通過讀、寫通訊端進行通訊。
網路連接函數
socket 建立通訊端
bind 綁定本機連接埠
connect 建立串連
listen 監聽連接埠
accept 接受串連
recv, recvfrom 資料接收
send, sendto 資料發送
close, shutdown 關閉通訊端
SOCKET socket(
int af,//地址族,一般是AF_INET,表示使用IP地址族
int type,//socket類型,SOCK_STREAM或SOCK_DGRAM
int protocol//協議類型,通常取值0
);
Winsock中使用sockaddr_in結構指定IP地址和連接埠資訊
struct sockaddr_in{
short sin_family;
u_short sin_port;
struct in_addrsin_addr;
char sin_zero[8];
}
sin_family一般為AF_INET,表示使用IP地址族;sin_port是以網路位元組序表示的16位連接埠號碼;sin_addr是網路位元組序的32位IP地址;sin_zero欄位一般不用,用0填充
int connect(
SOCKET s,//將要串連的socket
const structsockaddr FAR * name, //目標socket地址
int namelen//地址參數(name)的長度
);
int send(
SOCKET s,
const char FAR * buf,//發送資料緩衝區
int len, //緩衝區長度
int flags//用於控制資料轉送方式,0表示按正常方式發送資料
);
傳回值:發送的位元組數
int recv(
SOCKET s,
char FAR * buf,//接收資料緩衝區
int len, //緩衝區長度
int flags //0表示接收的是正常資料,無特殊行為
);
傳回值:接收到的位元組數
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
wVersionRequested是一個WORD型(雙位元組型)數值,指定使用的版本號碼,對Winsock2.2而言,此參數的值為0x0202,也可以用宏MAKEWORD(2,2)來獲得
lpWSAData是一個指向WSADATA結構的指標,它返回關於Winsock實現的詳細資料
頂一下吧O(∩_∩)O謝謝支援