導航:首頁 > 文件教程 > makeword函數

makeword函數

發布時間:2024-07-13 02:00:30

『壹』 #include <winsock2.h>

#include <winsock2.h> /*socket通信,系統文件*/
#include <stdio.h>
#pragma comment( lib, "ws2_32.lib" ) /*載入了連接庫文件,實現通信程序的管理*/
void main()
{
WSADATA wsaData; /*存儲被WSAStartup函數調用後返回的Windows sockets數據*/
SOCKET ClientSocket; /*定義客戶端socket*/
SOCKADDR_IN ServerAddr; /*定義服務端socket變數*/
int ServerPort = 4000; /*服務端設置埠為4000*/
char *SendBuffer = "Hello World!"; /*發送數據*/
char ReceiveBuffer[1024] = ""; /*接收緩存*/
int Result;
/*WSAStartup是windows非同步套接字啟動命令;makeword創建一個WORD變數*/
if ((Result = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{
printf("WSAStartup failed with error %d\n", Result);
return ;
}
/*創建套接字UDP連接,AF_INET表示使用IPV4協議,SOCK_DGRAM是無連接報文類型,默認UDP協議*/
ClientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ClientSocket < 0)
{
printf("socket failed with error %d\n", WSAGetLastError());
return ;
}
ServerAddr.sin_family = AF_INET; /*對伺服器端socket通信地址結構賦值,通信域、port、address*/
ServerAddr.sin_port = htons(ServerPort);
ServerAddr.sin_addr.s_addr = inet_addr("192.168.1.9");
int len; /*sendto是UDP協議的文件傳輸函數,參數依次為客戶端socket、發送buf、長度、調用方式標志位、目的套接字地址、長度*/
if (len = sendto(ClientSocket, SendBuffer, strlen(SendBuffer), 0, (SOCKADDR*) &ServerAddr, sizeof(ServerAddr)) < 0)
{
printf("sendto failed with error %d\n", WSAGetLastError());
return ;
}
else
{
printf("Send the data:%s\n", SendBuffer);
}
int FromAddrSize = sizeof(ServerAddr);
memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer)); /*將ReceiveBuffer變數和ServerAddr地址變數清零*/
memset(&ServerAddr, 0, sizeof(ServerAddr));
/*接收來自客戶端的數據,參數意義與sendto同*/
if (len = recvfrom(ClientSocket, ReceiveBuffer, 1024, 0, (SOCKADDR*) &ServerAddr, &FromAddrSize) < 0)
{
printf("recvfrom failed with error %d\n", WSAGetLastError());
return ;
}
else
{
printf("Received Data:%s From :%s\n", ReceiveBuffer, inet_ntoa(ServerAddr.sin_addr));
}
if (closesocket(ClientSocket) == SOCKET_ERROR) /*關閉客戶端套接字*/
{
printf("closesocket failed with error %d\n", WSAGetLastError());
}
if (WSACleanup() == SOCKET_ERROR) /*釋放資源*/
{
printf("WSACleanup failed with error %d\n", WSAGetLastError());
}
}

『貳』 怎樣學習Windows 網路編程

新手必學:windows網路編程經典入門

作者:huyoo
對於一個windows網路編程初學者,下面方法是經典入門。
初學者建議不要用MFC提供的類,而用windows API做一個簡單伺服器和客戶端,這樣有助於對socket編程機制的理解。

為了簡單起見,應用程序是基於MFC的標准對話框。

Winsock用WINDOWS API實現:

(1)伺服器端有兩個線程:
主線程 — 你需要編寫以下函數來實現

#define NETWORK_EVENT USER_MESSAGE+100 file://定義網路事件
sockaddr_in clientaddr; file://暫時存放客戶端IP地址

file://自己定義消息映射函數,將上面定義的網路事件映射到處理函數
file://OnNetEvent為網路事件處理函數,它在下面定義
ON_MESSAGE(NETWORK_EVENT, OnNetEvent);

在你對話框中的初始化函數中調用下面的初始化網路的子函數
BOOL InitNetwork() file://初始化網路
{
file://初始化TCP協議
BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(ret != 0)
{
MessageBox("初始化套接字失敗!");
return FALSE;
}

file://創建伺服器端套接字
SOCKET serverSocket
= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(serverSocket == INVALID_SOCKET)
{
MessageBox("創建套接字失敗!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}

file://綁定到本地一個埠上
sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_port = htons(1688);
localaddr.sin_addr.s_addr = 0;
if(bind(serverSocket ,(const struct sockaddr*)&localaddr,
sizeof(sockaddr)) == SOCKET_ERROR)
{
MessageBox("綁定地址失敗!");
closesocket(m_Socket);
WSACleanup();
return FALSE;
}

file://注冊網路非同步事件,m_hWnd為應用程序的主對話框或主窗口的句柄
WSAAsyncSelect(serverSocket, m_hWnd, NETWORK_EVENT,
FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE);

listen(serverSocket, 5); file://設置偵聽模式

return TRUE;
}

file://定義網路事件的響應函數
void OnNetEvent(WPARAM wParam, LPARAM lParam)
{
file://調用API函數,得到網路事件類型
int iEvent = WSAGETSELECTEVENT(lParam);

file://得到發出此事件的客戶端套接字
SOCKET pSock = (SOCKET)wParam;
switch(iEvent)
{
case FD_ACCEPT: file://客戶端連接請求
{
OnAccept();

break;
}
case FD_CLOSE: file://客戶端斷開事件:
{
OnClose(pSock);
break;
}
case FD_READ: file://網路數據包到達事件
{
OnReceive(pSock);
break;
}
case FD_WRITE: file://發送網路數據事件
{
OnSend(pSock);
break;
}
default: break;
}
}

void OnAccept(SOCET pSock) file://響應客戶端連接請求函數
{
int len = sizeof(sockaddr);

file://調用API函數,接受連接,並返回一個新套接字
file://還可以獲得客戶端的IP地址
SOCKET clientSocket = accept(serverSocket,
(struct sockaddr*)&clientaddr, &len);

file://為新的socket注冊非同步事件,注意沒有Accept事件
if(WSAAsyncSelect(clientSocket ,m_hWnd, IP_EVENT,
FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
{
MessageBox("注冊非同步事件失敗!");
return;
}

file://自編函數,將此客戶端的相關信息保存下來:套接字、
// IP地址、登陸時間
saveClientSocket(clientSocket,clientAddr,currentTimer);
}

void OnClose(SOCET pSock)
{
file://自編函數,結束與相應的客戶端的通信,釋放相應資源並做相應處理
endClientSocket(pSock);
}

void OnSend(SOCET pSock)
{
file://自編函數,在給客戶端發數據時做一些預處理
handleOnSend(pSock);
}

void OnReceive(SOCET pSock)
{
recv(...); file://調用API函數,讀出網路緩沖區中的數據包

file://自編函數,將此數據包和發出此數據的客戶端
file://clientSocket封裝成一條網路消息
buildNetMsg(...);

file://自編函數,將此網路消息放入一個消息隊列中,由工作線程去處理
saveNetMsg(...);
SetEvent(...); file://用事件對象觸發工作線程
}

客戶端登陸後,隨即把自己的計算機名發給伺服器,伺服器接到後,把它保存下來。這樣伺服器就可以顯示所有在線客戶端的信息了,包括:客戶端計算機名、IP地址、登陸時間等。

注意: 客戶端沒有OnAccept()函數,但有OnConnect()函數。

工作線程 —
在你的應用程序初始化時,創建並啟動一個工作線程

AfxBeginThread(WorkThread,this,THREAD_PRIORITY_NORMAL);
file://this可能為應用程序的主對話框或主窗口的句柄

UINT WorkThread(LPVOID pParam)
{
while(1)
{
file://等待多重事件到來
int ret = WaitForMultipleObject(...);

switch(ret)
{
case OBJECT_0:
{
if(bNewNetMsg) file://查看網路消息隊列是否有新的網路消息
{
readNetMsg(...); file://如有新的網路消息,則讀出
handleNetMsg(...); file://處理此網路消息
}
break;
}
case OBJECT_0 + 1:
{
file://做退出處理
break;
}
default: break;
}

return 0;
}

客戶端為單線程,登陸伺服器時,用connect()函數給伺服器發連接請求;
客戶端沒有OnAccept()函數,但有OnConnect()函數。
在OnConnect()函數里做發連接請求時的預處理;
在OnReceive()函數里響應並處理網路數據;
在OnClose()函數里響應伺服器的關閉事件;
在OnSend()函數里做發數據時的預處理;

如果你還想實現各客戶端之間的在線交流(即所謂的聊天室),你在客戶端還可以基於UDP協議
再做一套多點對多點的區域網組播模型模型,以後在和你聊,你先把上面的程序實現。

以上的I/O非同步模型基於Windows的消息機制,另外還可以用事件模型、重疊模型或完成埠模型,
建議你參考Windows網路編程指南之類的書。

如果你能對上面的機制很熟練,你肯定已經對Winsock編網路程序的機制有一定理解,接下來你可以進行更精彩的編程, 不僅可以在網上傳輸普通數據,而且還
以傳輸語音、視頻數據,你還可以自己做一個聊天室,和你的同學在實驗室的區域網里可以共同分享你的成果。

『叄』 socket編程。怎麼實現數據包的轉發C語言版的。

我也不知道····只好復制一份···共同學習~~ 要寫網路程序就必須用Socket,這是程序員都知道的。而且,面試的時候,我們也會問對方會不會Socket編程?一般來說,很多人都會說,Socket編程基本就是listen,accept以及send,write等幾個基本的操作。是的,就跟常見的文件操作一樣,只要寫過就一定知道。對於網路編程,我們也言必稱TCP/IP,似乎其它網路協議已經不存在了。對於TCP/IP,我們還知道TCP和UDP,前者可以保證數據的正確和可靠性,後者則允許數據丟失。最後,我們還知道,在建立連接前,必須知道對方的IP地址和埠號。除此,普通的程序員就不會知道太多了,很多時候這些知識已經夠用了。最多,寫服務程序的時候,會使用多線程來處理並發訪問。我們還知道如下幾個事實:1。一個指定的埠號不能被多個程序共用。比如,如果IIS佔用了80埠,那麼Apache就不能也用80埠了。2。很多防火牆只允許特定目標埠的數據包通過。3。服務程序在listen某個埠並accept某個連接請求後,會生成一個新的socket來對該請求進行處理。於是,一個困惑了我很久的問題就產生了。如果一個socket創建後並與80埠綁定後,是否就意味著該socket佔用了80埠呢?如果是這樣的,那麼當其accept一個請求後,生成的新的socket到底使用的是什麼埠呢(我一直以為系統會默認給其分配一個空閑的埠號)?如果是一個空閑的埠,那一定不是80埠了,於是以後的TCP數據包的目標埠就不是80了--防火牆一定會組織其通過的!實際上,我們可以看到,防火牆並沒有阻止這樣的連接,而且這是最常見的連接請求和處理方式。我的不解就是,為什麼防火牆沒有阻止這樣的連接?它是如何判定那條連接是因為connet80埠而生成的?是不是TCP數據包里有什麼特別的標志?或者防火牆記住了什麼東西?後來,我又仔細研讀了TCP/IP的協議棧的原理,對很多概念有了更深刻的認識。比如,在TCP和UDP同屬於傳輸層,共同架設在IP層(網路層)之上。而IP層主要負責的是在節點之間(End to End)的數據包傳送,這里的節點是一台網路設備,比如計算機。因為IP層只負責把數據送到節點,而不能區分上面的不同應用,所以TCP和UDP協議在其基礎上加入了埠的信息,埠於是標識的是一個節點上的一個應用。除了增加埠信息,UPD協議基本就沒有對IP層的數據進行任何的處理了。而TCP協議還加入了更加復雜的傳輸控制,比如滑動的數據發送窗口(Slice Window),以及接收確認和重發機制,以達到數據的可靠傳送。不管應用層看到的是怎樣一個穩定的TCP數據流,下面傳送的都是一個個的IP數據包,需要由TCP協議來進行數據重組。所以,我有理由懷疑,防火牆並沒有足夠的信息判斷TCP數據包的更多信息,除了IP地址和埠號。而且,我們也看到,所謂的埠,是為了區分不同的應用的,以在不同的IP包來到的時候能夠正確轉發。TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作介面。就像操作系統會提供標準的編程介面,比如Win32編程介面一樣,TCP/IP也必須對外提供編程介面,這就是Socket編程介面--原來是這么回事啊!在Socket編程介面里,設計者提出了一個很重要的概念,那就是socket。這個socket跟文件句柄很相似,實際上在BSD系統里就是跟文件句柄一樣存放在一樣的進程句柄表裡。這個socket其實是一個序號,表示其在句柄表中的位置。這一點,我們已經見過很多了,比如文件句柄,窗口句柄等等。這些句柄,其實是代表了系統中的某些特定的對象,用於在各種函數中作為參數傳入,以對特定的對象進行操作--這其實是C語言的問題,在C++語言里,這個句柄其實就是this指針,實際就是對象指針啦。現在我們知道,socket跟TCP/IP並沒有必然的聯系。Socket編程介面在設計的時候,就希望也能適應其他的網路協議。所以,socket的出現只是可以更方便的使用TCP/IP協議棧而已,其對TCP/IP進行了抽象,形成了幾個最基本的函數介面。比如create,listen,accept,connect,read和write等等。現在我們明白,如果一個程序創建了

閱讀全文

與makeword函數相關的資料

熱點內容
網路怎麼校線 瀏覽:546
會玩app稀有寶箱裡面有什麼 瀏覽:718
打開icloud備份文件在哪裡看 瀏覽:602
一個表格多個數據怎麼樣查找數據 瀏覽:466
qq飛車微信簽到app有哪些 瀏覽:299
如何製作虛擬貨幣app 瀏覽:303
ug50能通過補丁升級到高版本嗎 瀏覽:766
dxf文件cad打不開的原因 瀏覽:525
2012怎麼改域用戶密碼 瀏覽:550
dtv網路電視手機版下載 瀏覽:954
mfc100u放在哪個文件夾 瀏覽:359
javaweb插件 瀏覽:58
pto密碼忘記 瀏覽:567
logo競賽教程 瀏覽:481
貴陽去哪裡學編程比較好 瀏覽:132
java將string轉為json 瀏覽:291
ppt2013製作exe文件 瀏覽:80
linux文件只讀不能復制 瀏覽:597
開關代碼 瀏覽:91
word繪圖板 瀏覽:359

友情鏈接