資料報套接字——簡單的回射伺服器示例
阿新 • • 發佈:2019-01-04
文章目錄
Server
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int __cdecl main(int argc, char **argv) { WSADATA wsaData; int iResult; SOCKET ServerSocket = INVALID_SOCKET; struct addrinfo *result = NULL; struct addrinfo hints; sockaddr_in clientaddr; int clientlen = sizeof(clientaddr); int iSendResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; //初始化WinSock iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if(iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); //宣告IPV4地址族,流式套接字,UDP協議 hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; hints.ai_flags = AI_PASSIVE; //解析伺服器地址和埠號 iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result); if(iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } //為無連線的伺服器建立套接字 ServerSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if(ServerSocket == INVALID_SOCKET) { printf("socket failed with error: %ld\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } //為監聽套接字繫結本地地址和埠號 iResult = bind(ServerSocket, result->ai_addr, (int)result->ai_addrlen); if(iResult == SOCKET_ERROR) { printf("bind failed with error: %d\n", WSAGetLastError()); freeaddrinfo(result); closesocket(ServerSocket); WSACleanup(); return 1; } freeaddrinfo(result); printf("UDP server starting\n"); ZeroMemory(&clientaddr, sizeof(clientaddr)); //recvfrom函式直接在引數中指定接收資料的源地址 iResult = recvfrom(ServerSocket, recvbuf, recvbuflen, 0, (SOCKADDR*)&clientaddr, &clientlen); if(iResult > 0) { //情況1:成功接收到資料 printf("Bytes received: %d\n", iResult); //將緩衝區的內容回送給客戶端 //sendto函式也是同理,在引數中指定資料要傳送到的目的地址 iSendResult = sendto(ServerSocket, recvbuf, iResult, 0, (SOCKADDR*)&clientaddr, clientlen); if(iSendResult == SOCKET_ERROR){ printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ServerSocket); WSACleanup(); return 1; } printf("Bytes sent: %d\n", iSendResult); } else if(iResult == 0) //情況2:關閉連線 printf("Connection closing...\n"); else { //情況3:接收發生錯誤 printf("recv failed with error: %d\n", WSAGetLastError()); closesocket(ServerSocket); WSACleanup(); return 1; } //關閉套接字 closesocket(ServerSocket); //釋放資源 WSACleanup(); return 0; }
Client
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> #pragma comment (lib, "Ws2_32.lib") #pragma comment (lib, "Mswsock.lib") #pragma comment (lib, "AdvApi32.lib") #define DEFAULT_BUFLEN 512 #define DEFAULT_PORT "27015" int __cdecl main(int argc, char **argv) { WSADATA wsaData; SOCKET ConnectLessSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints ; char *sendbuf = "this is a test"; char recvbuf[DEFAULT_BUFLEN]; int iResult; int recvbuflen = DEFAULT_BUFLEN; if(argc != 2) { printf("usage: %s server-name\n", argv[0]); return 1; } //初始化套接字 iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if(iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); return 1; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; //解析伺服器地址和埠號 iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); if(iResult != 0) { printf("getaddrinfo failed with error: %d\n", iResult); WSACleanup(); return 1; } //建立資料報套接字 ConnectLessSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if(ConnectLessSocket == INVALID_SOCKET) { printf("scoket failed with error: %ld\n", WSAGetLastError()); WSACleanup(); return 1; } //傳送緩衝區中的測試資料 iResult = sendto(ConnectLessSocket, sendbuf, (int)strlen(sendbuf), 0, result->ai_addr, (int)result->ai_addrlen); if(iResult == SOCKET_ERROR) { printf("send failed with error: %d\n", WSAGetLastError()); closesocket(ConnectLessSocket); WSACleanup(); return 1; } freeaddrinfo(result); printf("Bytes Sent: %ld\n", iResult); //接收資料 iResult = recvfrom(ConnectLessSocket, recvbuf, recvbuflen, 0, NULL, NULL); if(iResult > 0) printf("Bytes received: %d\n", iResult); else if(iResult == 0) printf("Connection closed\n"); else printf("recv failed with error: %d\n", WSAGetLastError()); //關閉套接字 closesocket(ConnectLessSocket); //釋放資源 WSACleanup(); return 0; }