采用的是VC2008,控制台應用程序,使用UDP編寫。
1、服務端代碼
//UDPServer.cpp
#include <WinSock2.h> #include <stdio.h> #define SERVERPORT 6000 //服務端口號 #pragma comment(lib, "WS2_32.lib") int main(int argc, char *argv[]) { //加載套接字庫 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return -1; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return -1; } /* The WinSock DLL is acceptable. Proceed. */ //創建套接字 SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, 0); if (INVALID_SOCKET == sockServer) { printf("socket() called failed! The error code is: %d\n", WSAGetLastError()); return -1; } else { printf("socket() called succesful!\n"); } //服務器端 SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrServer.sin_family = AF_INET; addrServer.sin_port = htons(SERVERPORT); //綁定套接字 err = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); if (SOCKET_ERROR == err) { printf("bind() called failed! The error code is: %d\n", WSAGetLastError()); return -1; } else { printf("bind() called successful!\n"); } //等待並接收數據 SOCKADDR_IN addrClient;//用於接收發送端的地址信息 int len = sizeof(SOCKADDR); char recvBuf[100]; recvfrom(sockServer, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len); //打印接收到的數據 printf("receive data:%s from client [%s,%d]", recvBuf, inet_ntoa(addrClient.sin_addr), addrClient.sin_port); //關閉套接字 closesocket(sockServer); //終止套接字庫的使用 WSACleanup(); return 0; }
2、客戶端代碼
//UDPClient.cpp
#include <WinSock2.h> #include <stdio.h> #define SERVERPORT 6000 //服務端口號 #pragma comment(lib, "WS2_32.lib") int main(int argc, char *argv[]) { //加載套接字庫 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return -1; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return -1; } //創建套接字 SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0); if (INVALID_SOCKET == sockClient) { printf("socket() called failed! The error code is: %d\n", WSAGetLastError()); return -1; } else { printf("socket() called succesful!\n"); } SOCKADDR_IN addrServer; addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrServer.sin_family = AF_INET; addrServer.sin_port = htons(SERVERPORT); //發送數據 err = sendto(sockClient, "Hello", strlen("Hello")+1, 0, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); if (SOCKET_ERROR == err) { printf("sendto() called failed! The error code is: %s\n", WSAGetLastError()); return -1; } else { printf("sendto() called successful!\n"); } //關閉套接字 closesocket(sockClient); //終止套接字庫的使用 WSACleanup(); return 0; }
注意:上面兩部分代碼中的
#pragma comment(lib, "WS2_32.lib")
可以刪除,而改為設置程序屬性,具體如下步驟:
server 和 client 都要"項目屬性"--->"配置屬性"----> "鏈接"----> "輸入" --->"附加依賴項"中添加"ws2_32.lib"。
先啟動服務端UDPServer程序,再啟動客戶端UDPClient程序,運行結果如下:
服務端UDPServer
客戶端UDPClient
此時服務端UDPServer的結果會發生變化,會受到客戶端發送過來的數據,如下圖所示:
參考資料:
1、《VC++深入詳解》 第14章網絡編程 ,孫鑫主編
2、MSDN幫助文檔
原文鏈接:VC++ UDP網絡控制台程序