无论是tcp还是udp 服务器都必须绑定prot、Ip,客户端可以有选择性。
udp单播: 单播只能是发送方往接收方指定的IP 端口发送数据
组播需具备的条件 1、接收方设置组播属性及组播号 2、发送方往接收方定义的组播地址发送 3、服务器客户端端口号需要一致
广播需具备的条件 1、接收方设置广播属性 2、发送方往接收方定义的组播地址发送 3、服务器客户端端口号需要一致
组播和单播的区别:组播可以多设置一个IP(这里称为为组播地址224打头的),发送方除了可以往接收方绑定的IP发送,也可以 往接收方设置的组播ip发送数据。
组播和广播的区别:广播需要设置启动接收广播属性,发送方除了可以往接收方绑定的IP发送,也可以往255同网段IP发送。
这三种udp模型 客户端的实现没有区别,区别仅仅在于发送的网络IP不一样
广播是不会被路由器转发的,特点局域网通信,局域网游戏,客户端的统计 局域网群发等。
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp unicast server code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*udp和tcp客户端其实都可以绑定自身的IP端口也可以不绑定,
不绑定的话系统会为你默认分配,而服务器则必须绑定端口 IP*/
#include <Winsock2.h>
#include <iostream>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
// Step 1. Ask system for a socket.this socket is waiter
SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sockServer == INVALID_SOCKET)
{
return 1;
}
//Step 2. bind the socket to a local address and port.接待套接字
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
addrServer.sin_port = 30001;
if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
sizeof addrServer) == SOCKET_ERROR)
{
return 1;
}
char buf[100] = { 0 };
sockaddr_in addrClient;
int iSize = sizeof(addrClient);
//recvfrom是阻塞的
int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);
closesocket(sockServer);
WSACleanup();
return 0;
}
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp unicast Client code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Winsock2.h>
#include <iostream>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
// Step 1. Ask system for a socket.this socket is waiter
SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sock2Server == INVALID_SOCKET)
{
return 1;
}
//绑定自己的port 客户端也可以绑定自己的port ip 指定数据从什么端口出去
//sockaddr_in addrBind = { 0 };
//addrBind.sin_family = AF_INET;
//addrBind.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
//addrBind.sin_port = 30002;
//if (::bind(sock2Server, reinterpret_cast<const sockaddr*>(&addrBind),
// sizeof addrBind) == SOCKET_ERROR)
//{
// return 1;
//}
//设置接收方的port ip 下面的端口 ip需要和服务器一致
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
addrServer.sin_port = 30001;
sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));
closesocket(sock2Server);
WSACleanup();
return 0;
}
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp muticast server code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Winsock2.h>
#include <iostream>
#include <thread>
#include<Ws2tcpip.h> //需要加上此头文件
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
// Step 1. Ask system for a socket.this socket is waiter
SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sockServer == INVALID_SOCKET)
{
return 1;
}
//Step 2. bind the socket to a local address and port.接待套接字
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
addrServer.sin_port = 30001;
if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
sizeof addrServer) == SOCKET_ERROR)
{
return 1;
}
//设置接收组播属性
ip_mreq mrq;
mrq.imr_multiaddr.S_un.S_addr = inet_addr("224.0.0.11");//设置组播地址 满足前面是224即可224.0.0.1不能用
mrq.imr_interface.S_un.S_addr = 0; //设置自动选择网卡上面接收组播
if (setsockopt(sockServer, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<const char*>(&mrq), sizeof(mrq)) == SOCKET_ERROR)
{
return 1;
}
char buf[100] = { 0 };
sockaddr_in addrClient;
int iSize = sizeof(addrClient);
int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);
closesocket(sockServer);
WSACleanup();
return 0;
}
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp muticast client code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Winsock2.h>
#include <iostream>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sock2Server == INVALID_SOCKET)
{
return 1;
}
//设置接收方的port ip 下面的端口
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
//点对点的也可以
//addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
//往服务器组播地址发也可以,相比单播多一个选择性
addrServer.sin_addr.S_un.S_addr = inet_addr("224.0.0.11");
addrServer.sin_port = 30001;
sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));
closesocket(sock2Server);
WSACleanup();
return 0;
}
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp broadcast server code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//具备广播的条件 1、接收方设置广播属性 2、发送方往同网段的255IP地址发送 3、服务器客户端端口号需要一致
#include <Winsock2.h>
#include <iostream>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
// Step 1. Ask system for a socket.this socket is waiter
SOCKET sockServer = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sockServer == INVALID_SOCKET)
{
return 1;
}
//Step 2. bind the socket to a local address and port.接待套接字
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
addrServer.sin_port = 30001;
if (::bind(sockServer, reinterpret_cast<const sockaddr*>(&addrServer),
sizeof addrServer) == SOCKET_ERROR)
{
return 1;
}
//设置接收广播属性 要设置了广播属性才可以接收广播消息
bool bEnableBroadcast = true;
if (setsockopt(sockServer, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<const char*>(&bEnableBroadcast), sizeof(bEnableBroadcast)) == SOCKET_ERROR)
{
return 1;
}
char buf[100] = { 0 };
sockaddr_in addrClient;
int iSize = sizeof(addrClient);
int iResult = recvfrom(sockServer, buf, 100, 0, reinterpret_cast<sockaddr*>(&addrClient), &iSize);
closesocket(sockServer);
WSACleanup();
return 0;
}
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
udp broadcast client code
/------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include <Winsock2.h>
#include <iostream>
#include <thread>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int main(void)
{
/* 初始化winsock2库 */
//Step 0. Initialize winsock2 library...
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
return 1;
}
// Step 1. Ask system for a socket.this socket is waiter
SOCKET sock2Server = ::socket(PF_INET, SOCK_DGRAM, 0);
if (sock2Server == INVALID_SOCKET)
{
return 1;
}
//广播中服务器设置了广播属性的话 下
//设置接收方的port ip 下面的端口
sockaddr_in addrServer = { 0 };
addrServer.sin_family = AF_INET;
//点对点的也可以
//addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.134");
//往255这个网段发的话 只要是设置了广播属性的服务器都可以接收到数据
addrServer.sin_addr.S_un.S_addr = inet_addr("88.88.106.255");
addrServer.sin_port = 30001;
sendto(sock2Server, "hello", 6, 0, reinterpret_cast<sockaddr*>(&addrServer), sizeof(addrServer));
closesocket(sock2Server);
WSACleanup();
return 0;
}