1. 辅助函数(common.h)
#ifndef CPP_NETWORK_COMMUNICATION_COMMON_H
#define CPP_NETWORK_COMMUNICATION_COMMON_H
#include <WinSock2.h>
#include <Ws2tcpip.h>
#include <cstdio>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
#define INTERFACE_ADDRESS "127.0.0.1"
#define MULTICAST_ADDRESS "239.127.3.5"
#define MULTICAST_PORT 7667
#define BUFFER_SIZE (1024)
#define TCP_SERVER_PORT (8000)
#define TCP_Client_PORT (8001)
#define UDP_SERVER_PORT (7667)
#define UDP_CLIENT_PORT (7668)
#define COUNT (5)
#ifdef DEBUG
#define DEBUG_FUNCTION_NAME() \
{ \
printf("================================================================\n"); \
printf("%s\n", __func__); \
}
#define DEBUG_LOG(format, ...) \
{ \
printf("LOG:[%s:%d->%s] " format, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
}
#else
#define DEBUG_FUNCTION_NAME()
#define DEBUG_LOG(format, ...)
#endif
void show_error_code()
{
int error_code = WSAGetLastError();
switch (error_code)
{
case 0:
std::cout << "ERROR CODE (" << error_code << " ): SUCCESS" << std::endl;
break;
case WSA_INVALID_HANDLE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_INVALID_HANDLE" << std::endl;
break;
case WSA_NOT_ENOUGH_MEMORY:
std::cout << "ERROR CODE (" << error_code << " ): WSA_NOT_ENOUGH_MEMORY" << std::endl;
break;
case WSA_INVALID_PARAMETER:
std::cout << "ERROR CODE (" << error_code << " ): WSA_INVALID_PARAMETER" << std::endl;
break;
case WSA_OPERATION_ABORTED:
std::cout << "ERROR CODE (" << error_code << " ): WSA_OPERATION_ABORTED" << std::endl;
break;
case WSA_IO_INCOMPLETE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_IO_INCOMPLETE" << std::endl;
break;
case WSA_IO_PENDING:
std::cout << "ERROR CODE (" << error_code << " ): WSA_IO_PENDING" << std::endl;
break;
case WSAEINTR:
std::cout << "ERROR CODE (" << error_code << " ): WSAEINTR" << std::endl;
break;
case WSAEBADF:
std::cout << "ERROR CODE (" << error_code << " ): WSAEBADF" << std::endl;
break;
case WSAEACCES:
std::cout << "ERROR CODE (" << error_code << " ): WSAEACCES" << std::endl;
break;
case WSAEFAULT:
std::cout << "ERROR CODE (" << error_code << " ): WSAEFAULT" << std::endl;
break;
case WSAEINVAL:
std::cout << "ERROR CODE (" << error_code << " ): WSAEINVAL" << std::endl;
break;
case WSAEMFILE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEMFILE" << std::endl;
break;
case WSAEWOULDBLOCK:
std::cout << "ERROR CODE (" << error_code << " ): WSAEWOULDBLOCK" << std::endl;
break;
case WSAEINPROGRESS:
std::cout << "ERROR CODE (" << error_code << " ): WSAEINPROGRESS" << std::endl;
break;
case WSAEALREADY:
std::cout << "ERROR CODE (" << error_code << " ): WSAEALREADY" << std::endl;
break;
case WSAENOTSOCK:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOTSOCK" << std::endl;
break;
case WSAEDESTADDRREQ:
std::cout << "ERROR CODE (" << error_code << " ): WSAEDESTADDRREQ" << std::endl;
break;
case WSAEMSGSIZE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEMSGSIZE" << std::endl;
break;
case WSAEPROTOTYPE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEPROTOTYPE" << std::endl;
break;
case WSAENOPROTOOPT:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOPROTOOPT" << std::endl;
break;
case WSAEPROTONOSUPPORT:
std::cout << "ERROR CODE (" << error_code << " ): WSAEPROTONOSUPPORT" << std::endl;
break;
case WSAESOCKTNOSUPPORT:
std::cout << "ERROR CODE (" << error_code << " ): WSAESOCKTNOSUPPORT" << std::endl;
break;
case WSAEOPNOTSUPP:
std::cout << "ERROR CODE (" << error_code << " ): WSAEOPNOTSUPP" << std::endl;
break;
case WSAEADDRINUSE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEADDRINUSE" << std::endl;
break;
case WSAEADDRNOTAVAIL:
std::cout << "ERROR CODE (" << error_code << " ): WSAEADDRNOTAVAIL" << std::endl;
break;
case WSAENETDOWN:
std::cout << "ERROR CODE (" << error_code << " ): WSAENETDOWN" << std::endl;
break;
case WSAENETUNREACH:
std::cout << "ERROR CODE (" << error_code << " ): WSAENETUNREACH" << std::endl;
break;
case WSAENETRESET:
std::cout << "ERROR CODE (" << error_code << " ): WSAENETRESET" << std::endl;
break;
case WSAECONNABORTED:
std::cout << "ERROR CODE (" << error_code << " ): WSAECONNABORTED" << std::endl;
break;
case WSAECONNRESET:
std::cout << "ERROR CODE (" << error_code << " ): WSAECONNRESET" << std::endl;
break;
case WSAENOBUFS:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOBUFS" << std::endl;
break;
case WSAEISCONN:
std::cout << "ERROR CODE (" << error_code << " ): WSAEISCONN" << std::endl;
break;
case WSAENOTCONN:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOTCONN" << std::endl;
break;
case WSAESHUTDOWN:
std::cout << "ERROR CODE (" << error_code << " ): WSAESHUTDOWN" << std::endl;
break;
case WSAETOOMANYREFS:
std::cout << "ERROR CODE (" << error_code << " ): WSAETOOMANYREFS" << std::endl;
break;
case WSAETIMEDOUT:
std::cout << "ERROR CODE (" << error_code << " ): WSAETIMEDOUT" << std::endl;
break;
case WSAECONNREFUSED:
std::cout << "ERROR CODE (" << error_code << " ): WSAECONNREFUSED" << std::endl;
break;
case WSAELOOP:
std::cout << "ERROR CODE (" << error_code << " ): WSAELOOP" << std::endl;
break;
case WSAENAMETOOLONG:
std::cout << "ERROR CODE (" << error_code << " ): WSAENAMETOOLONG" << std::endl;
break;
case WSAEHOSTDOWN:
std::cout << "ERROR CODE (" << error_code << " ): WSAEHOSTDOWN" << std::endl;
break;
case WSAEHOSTUNREACH:
std::cout << "ERROR CODE (" << error_code << " ): WSAEHOSTUNREACH" << std::endl;
break;
case WSAENOTEMPTY:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOTEMPTY" << std::endl;
break;
case WSAEPROCLIM:
std::cout << "ERROR CODE (" << error_code << " ): WSAEPROCLIM" << std::endl;
break;
case WSAEUSERS:
std::cout << "ERROR CODE (" << error_code << " ): WSAEUSERS" << std::endl;
break;
case WSAEDQUOT:
std::cout << "ERROR CODE (" << error_code << " ): WSAEDQUOT" << std::endl;
break;
case WSAESTALE:
std::cout << "ERROR CODE (" << error_code << " ): WSAESTALE" << std::endl;
break;
case WSAEREMOTE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEREMOTE" << std::endl;
break;
case WSASYSNOTREADY:
std::cout << "ERROR CODE (" << error_code << " ): WSASYSNOTREADY" << std::endl;
break;
case WSAVERNOTSUPPORTED:
std::cout << "ERROR CODE (" << error_code << " ): WSAVERNOTSUPPORTED" << std::endl;
break;
case WSANOTINITIALISED:
std::cout << "ERROR CODE (" << error_code << " ): WSANOTINITIALISED" << std::endl;
break;
case WSAEDISCON:
std::cout << "ERROR CODE (" << error_code << " ): WSAEDISCON" << std::endl;
break;
case WSAENOMORE:
std::cout << "ERROR CODE (" << error_code << " ): WSAENOMORE" << std::endl;
break;
case WSAECANCELLED:
std::cout << "ERROR CODE (" << error_code << " ): WSAECANCELLED" << std::endl;
break;
case WSAEINVALIDPROCTABLE:
std::cout << "ERROR CODE (" << error_code << " ): WSAEINVALIDPROCTABLE" << std::endl;
break;
case WSAEINVALIDPROVIDER:
std::cout << "ERROR CODE (" << error_code << " ): WSAEINVALIDPROVIDER" << std::endl;
break;
case WSAEPROVIDERFAILEDINIT:
std::cout << "ERROR CODE (" << error_code << " ): WSAEPROVIDERFAILEDINIT" << std::endl;
break;
case WSASYSCALLFAILURE:
std::cout << "ERROR CODE (" << error_code << " ): WSASYSCALLFAILURE" << std::endl;
break;
case WSASERVICE_NOT_FOUND:
std::cout << "ERROR CODE (" << error_code << " ): WSASERVICE_NOT_FOUND" << std::endl;
break;
case WSATYPE_NOT_FOUND:
std::cout << "ERROR CODE (" << error_code << " ): WSATYPE_NOT_FOUND" << std::endl;
break;
case WSA_E_NO_MORE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_E_NO_MORE" << std::endl;
break;
case WSA_E_CANCELLED:
std::cout << "ERROR CODE (" << error_code << " ): WSA_E_CANCELLED" << std::endl;
break;
case WSAEREFUSED:
std::cout << "ERROR CODE (" << error_code << " ): WSAEREFUSED" << std::endl;
break;
case WSAHOST_NOT_FOUND:
std::cout << "ERROR CODE (" << error_code << " ): WSAHOST_NOT_FOUND" << std::endl;
break;
case WSATRY_AGAIN:
std::cout << "ERROR CODE (" << error_code << " ): WSATRY_AGAIN" << std::endl;
break;
case WSANO_RECOVERY:
std::cout << "ERROR CODE (" << error_code << " ): WSANO_RECOVERY" << std::endl;
break;
case WSANO_DATA:
std::cout << "ERROR CODE (" << error_code << " ): WSANO_DATA" << std::endl;
break;
case WSA_QOS_RECEIVERS:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_RECEIVERS" << std::endl;
break;
case WSA_QOS_SENDERS:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_SENDERS" << std::endl;
break;
case WSA_QOS_NO_SENDERS:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_NO_SENDERS" << std::endl;
break;
case WSA_QOS_NO_RECEIVERS:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_NO_RECEIVERS" << std::endl;
break;
case WSA_QOS_REQUEST_CONFIRMED:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_REQUEST_CONFIRMED" << std::endl;
break;
case WSA_QOS_ADMISSION_FAILURE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_ADMISSION_FAILURE" << std::endl;
break;
case WSA_QOS_POLICY_FAILURE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_POLICY_FAILURE" << std::endl;
break;
case WSA_QOS_BAD_STYLE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_BAD_STYLE" << std::endl;
break;
case WSA_QOS_BAD_OBJECT:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_BAD_OBJECT" << std::endl;
break;
case WSA_QOS_TRAFFIC_CTRL_ERROR:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_TRAFFIC_CTRL_ERROR" << std::endl;
break;
case WSA_QOS_GENERIC_ERROR:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_GENERIC_ERROR" << std::endl;
break;
case WSA_QOS_ESERVICETYPE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_ESERVICETYPE" << std::endl;
break;
case WSA_QOS_EFLOWSPEC:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFLOWSPEC" << std::endl;
break;
case WSA_QOS_EPROVSPECBUF:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EPROVSPECBUF" << std::endl;
break;
case WSA_QOS_EFILTERSTYLE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFILTERSTYLE" << std::endl;
break;
case WSA_QOS_EFILTERTYPE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFILTERTYPE" << std::endl;
break;
case WSA_QOS_EFILTERCOUNT:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFILTERCOUNT" << std::endl;
break;
case WSA_QOS_EOBJLENGTH:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EOBJLENGTH" << std::endl;
break;
case WSA_QOS_EFLOWCOUNT:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFLOWCOUNT" << std::endl;
break;
case WSA_QOS_EUNKOWNPSOBJ:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EUNKOWNPSOBJ" << std::endl;
break;
case WSA_QOS_EPOLICYOBJ:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EPOLICYOBJ" << std::endl;
break;
case WSA_QOS_EFLOWDESC:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EFLOWDESC" << std::endl;
break;
case WSA_QOS_EPSFLOWSPEC:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EPSFLOWSPEC" << std::endl;
break;
case WSA_QOS_EPSFILTERSPEC:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_EPSFILTERSPEC" << std::endl;
break;
case WSA_QOS_ESDMODEOBJ:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_ESDMODEOBJ" << std::endl;
break;
case WSA_QOS_ESHAPERATEOBJ:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_ESHAPERATEOBJ" << std::endl;
break;
case WSA_QOS_RESERVED_PETYPE:
std::cout << "ERROR CODE (" << error_code << " ): WSA_QOS_RESERVED_PETYPE" << std::endl;
break;
default:
std::cout << "ERROR CODE (" << error_code << " ): Undefined" << std::endl;
break;
}
}
int release()
{
DEBUG_FUNCTION_NAME()
if (WSACleanup())
{
show_error_code();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int init(WSADATA &wsaData)
{
DEBUG_FUNCTION_NAME()
auto wVersionRequested = MAKEWORD(2, 2);
int major_version = LOBYTE(wVersionRequested);
int minor_version = HIBYTE(wVersionRequested);
std::cout << "Expected Major Version: " << major_version << std::endl;
std::cout << "Expected Minor Version: " << minor_version << std::endl;
int error_code = WSAStartup(wVersionRequested, &wsaData);
if (error_code)
{
printf("WSAStartup failed with error: %d\n", error_code);
return EXIT_FAILURE;
}
else
{
major_version = LOBYTE(wsaData.wVersion);
minor_version = HIBYTE(wsaData.wVersion);
std::cout << "Used Major Version: " << major_version << std::endl;
std::cout << "Used Minor Version: " << minor_version << std::endl;
major_version = LOBYTE(wsaData.wHighVersion);
minor_version = HIBYTE(wsaData.wHighVersion);
std::cout << "High Major Version: " << major_version << std::endl;
std::cout << "High Minor Version: " << minor_version << std::endl;
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
{
printf("Could not find a usable version of Winsock.dll\n");
release();
return EXIT_FAILURE;
}
printf("The Winsock 2.2 dll was found okay\n");
}
return EXIT_SUCCESS;
}
int get_host_name()
{
DEBUG_FUNCTION_NAME()
char host_name[256]{0};
if (SOCKET_ERROR == gethostname(host_name, 256))
{
show_error_code();
release();
return EXIT_FAILURE;
}
else
{
std::cout << "host name: " << host_name << std::endl;
}
return EXIT_SUCCESS;
}
int create_socket(SOCKET &local_socket, int type)
{
DEBUG_FUNCTION_NAME()
local_socket = socket(AF_INET, type, 0);
if (!(local_socket == INVALID_SOCKET))
return EXIT_SUCCESS;
show_error_code();
release();
return EXIT_FAILURE;
}
int bind_local(SOCKET &socket_server, ADDRESS_FAMILY family, ULONG in_addr, USHORT port)
{
DEBUG_FUNCTION_NAME()
SOCKADDR_IN local_addr;
memset(&local_addr, 0, sizeof(local_addr));
ZeroMemory(&local_addr, sizeof(local_addr));
local_addr.sin_family = family;
local_addr.sin_addr.s_addr = in_addr;
local_addr.sin_port = htons(port);
if (bind(socket_server, (SOCKADDR *)&local_addr, sizeof(local_addr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int connect_to_server(SOCKET &socket_client, ADDRESS_FAMILY family, ULONG in_addr, USHORT port)
{
DEBUG_FUNCTION_NAME()
SOCKADDR_IN remote_addr;
memset(&remote_addr, 0, sizeof(remote_addr));
ZeroMemory(&remote_addr, sizeof(remote_addr));
remote_addr.sin_family = family;
remote_addr.sin_addr.s_addr = in_addr;
remote_addr.sin_port = htons(port);
if (connect(socket_client, (SOCKADDR *)&remote_addr, sizeof(remote_addr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int start_listen(SOCKET &socket_server)
{
DEBUG_FUNCTION_NAME()
if (listen(socket_server, 5))
{
show_error_code();
release();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int wait_connect(SOCKET &socket_server, SOCKET &socket_client)
{
DEBUG_FUNCTION_NAME()
SOCKADDR_IN client_addr{0};
int len = sizeof(SOCKADDR);
memset(&client_addr, 0, len);
socket_client = accept(socket_server, (SOCKADDR *)&client_addr, &len);
if (INVALID_SOCKET == socket_client)
{
show_error_code();
release();
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int recv_message(SOCKET &socket_client, char *buffer, int &recv_length)
{
DEBUG_FUNCTION_NAME()
recv_length = recv(socket_client, buffer, BUFFER_SIZE, 0);
if (recv_length == 0)
{
std::cout << "The client is disconnected." << std::endl;
return EXIT_FAILURE;
}
else if (recv_length == SOCKET_ERROR)
{
show_error_code();
closesocket(socket_client);
return EXIT_FAILURE;
}
else if (recv_length < 0 && recv_length > BUFFER_SIZE)
{
std::cout << "recvieved length is not correct. length is " << recv_length << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int send_message(SOCKET &socket, char* buffer, int buffer_length)
{
DEBUG_FUNCTION_NAME()
int length = send(socket, buffer, buffer_length, 0);
if(SOCKET_ERROR == length)
{
show_error_code();
return EXIT_FAILURE;
}
std::cout << "Expected length is " << buffer_length << ", sent length is " << length << std::endl;
return EXIT_SUCCESS;
}
#endif
2. CMakeLists.txt
# 指定最低的CMAKE版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.17 FATAL_ERROR)
# 创建项目
PROJECT(cpp_network_communication)
if (CMAKE_BUILD_TYPE AND (CMAKE_BUILD_TYPE STREQUAL "Debug"))
add_compile_definitions(DEBUG)
endif()
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
# 指定CPLUSPLUS标准
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_C_STANDARD 11)
SET(CMAKE_C_STANDARD_REQUIRED ON)
ADD_EXECUTABLE(tcp_server tcp/tcp_server.cpp)
ADD_EXECUTABLE(tcp_client tcp/tcp_client.cpp)
ADD_EXECUTABLE(udp_server udp/udp_server.cpp)
ADD_EXECUTABLE(udp_client udp/udp_client.cpp)
ADD_EXECUTABLE(udp_server_boardcast udp/udp_server_boardcast.cpp)
ADD_EXECUTABLE(udp_client_boardcast udp/udp_client_boardcast.cpp)
ADD_EXECUTABLE(udp_server_multicast udp/udp_server_multicast.cpp)
ADD_EXECUTABLE(udp_client_multicast udp/udp_client_multicast.cpp)
ADD_EXECUTABLE(udp_server_multicast_config udp/udp_server_multicast_config.cpp)
3. TCP
3.1 服务器(tcp_server.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_server;
if (create_socket(socket_server, SOCK_STREAM))
return EXIT_FAILURE;
if (bind_local(socket_server, AF_INET, htonl(INADDR_ANY), TCP_SERVER_PORT))
return EXIT_FAILURE;
if (start_listen(socket_server))
return EXIT_FAILURE;
SOCKET socket_client;
std::cout << "waiting for client ..." << std::endl;
if (!wait_connect(socket_server, socket_client))
{
char buffer[BUFFER_SIZE + 1]{0};
for (size_t i = 0; i < COUNT; i++)
{
int length = 0;
std::cout << "waiting for data ..." << std::endl;
if (!recv_message(socket_client, buffer, length))
{
std::cout << "\trecv message: " << buffer << std::endl;
char *message = "server send client.";
send_message(socket_client, message, strlen(message) + 1);
}
std::cout << "\trecv message: index = " << i << std::endl;
}
closesocket(socket_client);
}
release();
system("PAUSE");
return EXIT_SUCCESS;
}
3.2 客户端(tcp_client.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_client;
if (create_socket(socket_client, SOCK_STREAM))
return EXIT_FAILURE;
if (bind_local(socket_client, AF_INET, inet_addr("127.0.0.1"), TCP_Client_PORT))
return EXIT_FAILURE;
if (connect_to_server(socket_client, AF_INET, inet_addr("127.0.0.1"), TCP_SERVER_PORT))
return EXIT_FAILURE;
for (int i = 0; i < COUNT; i++)
{
char *message = "client send to server.";
send_message(socket_client, message, strlen(message) + 1);
char buffer[BUFFER_SIZE]{0};
int recv_length;
recv_message(socket_client, buffer, recv_length);
std::cout << buffer << std::endl;
Sleep(1000);
}
closesocket(socket_client);
release();
system("PAUSE");
return EXIT_SUCCESS;
}
4. UDP 单播
4.1 服务器/(首次)接收端(udp_server.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_server;
if (create_socket(socket_server, SOCK_DGRAM))
return EXIT_FAILURE;
if (bind_local(socket_server, AF_INET, htonl(INADDR_ANY), UDP_SERVER_PORT))
return EXIT_FAILURE;
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN client_addr;
ZeroMemory(&client_addr, sizeof(SOCKADDR_IN));
int length = sizeof(SOCKADDR);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_server, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&client_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
char *message = "server send client.";
sendto(socket_server, message, strlen(message) + 1, 0, (SOCKADDR *)&client_addr, length);
}
closesocket(socket_server);
release();
system("PAUSE");
return 0;
}
4.2 客户端/(首次)发送端(udp_client.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_client;
if (create_socket(socket_client, SOCK_DGRAM))
return EXIT_FAILURE;
if (bind_local(socket_client, AF_INET, inet_addr("127.0.0.1"), UDP_CLIENT_PORT))
return EXIT_FAILURE;
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(UDP_SERVER_PORT);
char *message = "client send to server.";
sendto(socket_client, message, strlen(message) + 1, 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
int length = sizeof(SOCKADDR);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_client, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&server_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &server_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
Sleep(1000);
}
closesocket(socket_client);
system("PAUSE");
WSACleanup();
return 0;
}
5. 广播
5.1 服务器/(首次)接收端(udp_server_boardcast.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_server;
if (create_socket(socket_server, SOCK_DGRAM))
return EXIT_FAILURE;
bool bOpt = true;
setsockopt(socket_server, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));
if (bind_local(socket_server, AF_INET, htonl(INADDR_ANY), UDP_SERVER_PORT))
return EXIT_FAILURE;
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN client_addr;
ZeroMemory(&client_addr, sizeof(SOCKADDR_IN));
int length = sizeof(SOCKADDR);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_server, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&client_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
char *message = "server send client.";
sendto(socket_server, message, strlen(message) + 1, 0, (SOCKADDR *)&client_addr, length);
}
closesocket(socket_server);
release();
system("PAUSE");
return 0;
}
5.2 客户端/(首次)发送端(udp_client+bpardcast.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_client;
if (create_socket(socket_client, SOCK_DGRAM))
return EXIT_FAILURE;
if (bind_local(socket_client, AF_INET, inet_addr("127.0.0.1"), UDP_CLIENT_PORT))
return EXIT_FAILURE;
bool bOpt = true;
setsockopt(socket_client, SOL_SOCKET, SO_BROADCAST, (char *)&bOpt, sizeof(bOpt));
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(UDP_SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr("255.255.255.255");
char *message = "client send to server.";
sendto(socket_client, message, strlen(message) + 1, 0, (SOCKADDR *)&server_addr, sizeof(SOCKADDR));
int length = sizeof(SOCKADDR);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_client, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&server_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &server_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
Sleep(1000);
}
closesocket(socket_client);
system("PAUSE");
WSACleanup();
return 0;
}
6. 多/组播
6.1 服务器/(首次)接收端(udp_server_multicast.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_server;
if (create_socket(socket_server, SOCK_DGRAM))
return EXIT_FAILURE;
bool is_reuse_addr = true;
if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, (char *)&is_reuse_addr, sizeof(is_reuse_addr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
if (bind_local(socket_server, AF_INET, htonl(INADDR_ANY), UDP_SERVER_PORT))
return EXIT_FAILURE;
struct ip_mreq imr;
imr.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDRESS);
imr.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(socket_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, sizeof(imr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN client_addr;
ZeroMemory(&client_addr, sizeof(SOCKADDR_IN));
int length = sizeof(SOCKADDR);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_server, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&client_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
char *message = "server send to client.";
sendto(socket_server, message, strlen(message) + 1, 0, (SOCKADDR *)&client_addr, length);
}
closesocket(socket_server);
release();
system("PAUSE");
return 0;
}
6.1 客户端/(首次)发送端(udp_client_multicast.cpp)
#include "common/common.h"
int main()
{
WSADATA wsaData;
if (init(wsaData))
return EXIT_FAILURE;
SOCKET socket_client;
if (create_socket(socket_client, SOCK_DGRAM))
return EXIT_FAILURE;
bool is_reuse_addr = true;
if (setsockopt(socket_client, SOL_SOCKET, SO_REUSEADDR, (char *)&is_reuse_addr, sizeof(is_reuse_addr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
if (bind_local(socket_client, AF_INET, htonl(INADDR_ANY), UDP_CLIENT_PORT))
return EXIT_FAILURE;
struct ip_mreq imr;
imr.imr_multiaddr.s_addr = inet_addr(MULTICAST_ADDRESS);
imr.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(socket_client, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&imr, sizeof(imr)))
{
show_error_code();
release();
return EXIT_FAILURE;
}
for (size_t i = 0; i < COUNT; i++)
{
SOCKADDR_IN server_addr;
ZeroMemory(&server_addr, sizeof(SOCKADDR_IN));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MULTICAST_PORT);
server_addr.sin_addr.s_addr = inet_addr(MULTICAST_ADDRESS);
int length = sizeof(SOCKADDR);
char *message = "client send to server.";
sendto(socket_client, message, strlen(message) + 1, 0, (SOCKADDR *)&server_addr, length);
Sleep(1000);
char buffer[BUFFER_SIZE + 1]{0};
int recv_length = recvfrom(socket_client, buffer, BUFFER_SIZE, 0, (SOCKADDR *)&server_addr, &length);
char addr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &server_addr.sin_addr.s_addr, addr, INET_ADDRSTRLEN);
std::cout << "\tThe client addr is " << addr << std::endl;
std::cout << "\tThe length of recieved data is " << recv_length << std::endl;
std::cout << "\tThe recieved data is " << buffer << std::endl;
}
closesocket(socket_client);
release();
system("PAUSE");
return 0;
}