/ * 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] = '\0';
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] = '\0';
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时 并运行 Sender.exe&#34;你好&#34; 消息仅传递给单个进程。首先开始的过程 (例如 - 如果listner2.exe在listner1.exe之前启动,则所有消息仅发送到listner2。 如果我退出并重新启动listner2.exe,保持listner1.exe活着,然后 新邮件仅发送到listner1.exe。
我无法找到原因,多播不会发生。
此致 Sadanand
答案 0 :(得分:0)
在您的服务器中,您必须与多播地址通信:
/* 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);
}
此外,在我的计算机上,在侦听器中,我在多播成员资格之前进行绑定,以使侦听器正常工作。