多播不工作
Multicasting not working
/* Listner1.c 和 Listner2.c */
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <errno.h>
#include <Ws2tcpip.h>
#include <mswsock.h>
#define u_int32 UINT32
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define CPORT 12000
int main()
{
int iResult = 0;
WSADATA wsaData;
SOCKET RecvSocket;
struct sockaddr_in RecvAddr;
struct ip_mreq mreq;
char RecvBuf[1024];
int BufLen = 1024;
int yesopt = 1;
struct sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);
//-----------------------------------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error %d\n", iResult);
return 1;
}
//-----------------------------------------------
// Create a receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
if (setsockopt(RecvSocket,SOL_SOCKET, SO_REUSEADDR ,(char *) &yesopt ,sizeof(yesopt)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
memset(&RecvAddr,0,sizeof(RecvAddr));
RecvAddr.sin_family=AF_INET;
RecvAddr.sin_port=htons(CPORT);
RecvAddr.sin_addr.s_addr=inet_addr("192.168.0.104");
RecvBuf[0] = '[=10=]';
mreq.imr_interface.s_addr = inet_addr("192.168.0.104");
mreq.imr_multiaddr.s_addr = inet_addr("235.0.0.0");
iResult = setsockopt(RecvSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq,sizeof(mreq));
if (iResult < 0) {
perror("membership");
exit(1);
}
iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
wprintf(L"Receiving datagrams...\n");
while(1) {
iResult = recvfrom(RecvSocket,
RecvBuf, BufLen, 0, (SOCKADDR *) &RecvAddr, &SenderAddrSize);
if(iResult <= 0 ) break;
RecvBuf[iResult] = '[=10=]';
if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
break;
}
puts(RecvBuf);
}
//-----------------------------------------------
iResult = closesocket(RecvSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Clean up and exit.
// wprintf(L"Exiting.\n");
WSACleanup();
return 0;
}
我已经从上面的代码创建了 2 个进程...即
listner1.exe 和 listner2.exe ...
和以下用于发送消息的代码.. Sender.c ...
#include<io.h>
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<winsock2.h>
#include <errno.h>
#include <Ws2tcpip.h>
#include <mswsock.h>
#define u_int32 UINT32
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define HELLO_PORT 12000
#define HELLO_GROUP "192.168.0.104"
main(int argc, char *argv[])
{
WSADATA wsa;
struct sockaddr_in addr;
int fd;
char message[2000];
int opt = 1;
int iResult = 0;
strcpy ( message , argv[1] );
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("192.168.0.104");
addr.sin_port=htons(HELLO_PORT);
if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
}
当我在 2 个不同的命令中 运行 listner1.exe 和 listner2.exe windows
和 运行
Sender.exe "Hello there"
消息仅传递给单个进程。先启动的进程
(例如 - 如果 listner2.exe 在 listner1.exe 之前启动,则所有消息仅发送到 listner2。
如果我退出并重新启动 listner2.exe ,保持 listner1.exe 活着,那么
新邮件仅发送至 listner1.exe。
我找不到原因,多播没有发生。
问候
萨达南德
在您的服务器中,您必须与多播地址对话:
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("235.0.0.0");
addr.sin_port=htons(HELLO_PORT);
if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
此外,在我的计算机上,在侦听器中,我将绑定放在多播成员资格之前以使侦听器工作。
/* Listner1.c 和 Listner2.c */
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <errno.h>
#include <Ws2tcpip.h>
#include <mswsock.h>
#define u_int32 UINT32
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define CPORT 12000
int main()
{
int iResult = 0;
WSADATA wsaData;
SOCKET RecvSocket;
struct sockaddr_in RecvAddr;
struct ip_mreq mreq;
char RecvBuf[1024];
int BufLen = 1024;
int yesopt = 1;
struct sockaddr_in SenderAddr;
int SenderAddrSize = sizeof (SenderAddr);
//-----------------------------------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error %d\n", iResult);
return 1;
}
//-----------------------------------------------
// Create a receiver socket to receive datagrams
RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (RecvSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Bind the socket to any address and the specified port.
if (setsockopt(RecvSocket,SOL_SOCKET, SO_REUSEADDR ,(char *) &yesopt ,sizeof(yesopt)) < 0) {
perror("Reusing ADDR failed");
exit(1);
}
memset(&RecvAddr,0,sizeof(RecvAddr));
RecvAddr.sin_family=AF_INET;
RecvAddr.sin_port=htons(CPORT);
RecvAddr.sin_addr.s_addr=inet_addr("192.168.0.104");
RecvBuf[0] = '[=10=]';
mreq.imr_interface.s_addr = inet_addr("192.168.0.104");
mreq.imr_multiaddr.s_addr = inet_addr("235.0.0.0");
iResult = setsockopt(RecvSocket,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &mreq,sizeof(mreq));
if (iResult < 0) {
perror("membership");
exit(1);
}
iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
if (iResult != 0) {
wprintf(L"bind failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Call the recvfrom function to receive datagrams
// on the bound socket.
wprintf(L"Receiving datagrams...\n");
while(1) {
iResult = recvfrom(RecvSocket,
RecvBuf, BufLen, 0, (SOCKADDR *) &RecvAddr, &SenderAddrSize);
if(iResult <= 0 ) break;
RecvBuf[iResult] = '[=10=]';
if (iResult == SOCKET_ERROR) {
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
break;
}
puts(RecvBuf);
}
//-----------------------------------------------
iResult = closesocket(RecvSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket failed with error %d\n", WSAGetLastError());
return 1;
}
//-----------------------------------------------
// Clean up and exit.
// wprintf(L"Exiting.\n");
WSACleanup();
return 0;
}
我已经从上面的代码创建了 2 个进程...即 listner1.exe 和 listner2.exe ...
和以下用于发送消息的代码.. Sender.c ...
#include<io.h>
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<winsock2.h>
#include <errno.h>
#include <Ws2tcpip.h>
#include <mswsock.h>
#define u_int32 UINT32
#pragma comment(lib,"ws2_32.lib") //Winsock Library
#define HELLO_PORT 12000
#define HELLO_GROUP "192.168.0.104"
main(int argc, char *argv[])
{
WSADATA wsa;
struct sockaddr_in addr;
int fd;
char message[2000];
int opt = 1;
int iResult = 0;
strcpy ( message , argv[1] );
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(1);
}
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("192.168.0.104");
addr.sin_port=htons(HELLO_PORT);
if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
}
当我在 2 个不同的命令中 运行 listner1.exe 和 listner2.exe windows 和 运行 Sender.exe "Hello there" 消息仅传递给单个进程。先启动的进程 (例如 - 如果 listner2.exe 在 listner1.exe 之前启动,则所有消息仅发送到 listner2。 如果我退出并重新启动 listner2.exe ,保持 listner1.exe 活着,那么 新邮件仅发送至 listner1.exe。
我找不到原因,多播没有发生。
问候 萨达南德
在您的服务器中,您必须与多播地址对话:
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("235.0.0.0");
addr.sin_port=htons(HELLO_PORT);
if (sendto(fd,message,strlen(message),0,(struct sockaddr *) &addr,
sizeof(addr)) < 0) {
perror("sendto");
exit(1);
}
此外,在我的计算机上,在侦听器中,我将绑定放在多播成员资格之前以使侦听器工作。