Windows服务端
#include "stdafx.h"
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#define MCASTADDR "239.255.255.239" //本例使用的多播组地址。
#define MCASTPORT 9111 //绑定的本地端口号。
#define BUFSIZE 1024 //接收数据缓冲大小。
#pragma comment(lib,"Ws2_32.lib.")
int main( int argc,char ** argv)
{
WSADATA wsd;
struct sockaddr_in local,remote,from;
SOCKET sock,sockM;
char recvbuf[BUFSIZE];
int len = sizeof( struct sockaddr_in);
int ret; //初始化WinSock2.2
if( WSAStartup( MAKEWORD(2,2),&wsd) != 0 )
{
printf("WSAStartup() failed\n"); return -1;
}
if((sock=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0, WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF| WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("socket failed with:%d\n",WSAGetLastError());
WSACleanup();
return -1;
}
//将sock绑定到本机某端口上。
local.sin_family = AF_INET;
local.sin_port = htons(MCASTPORT);
local.sin_addr.s_addr = INADDR_ANY;
if( bind(sock,(struct sockaddr*)&local,sizeof(local)) == SOCKET_ERROR )
{
printf( "bind failed with:%d \n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
} //加入多播组
remote.sin_family = AF_INET;
remote.sin_port = htons(MCASTPORT);
remote.sin_addr.s_addr = inet_addr( MCASTADDR );
if(( sockM = WSAJoinLeaf(sock,(SOCKADDR*)&remote,sizeof(remote), NULL,NULL,NULL,NULL, JL_BOTH)) == INVALID_SOCKET)
{
printf("WSAJoinLeaf() failed:%d\n",WSAGetLastError());
closesocket(sock);
WSACleanup();
return -1;
} //接收多播数据,当接收到的数据为"QUIT"时退出。
while(1)
{
if(( ret = recvfrom(sock,recvbuf,BUFSIZE,0, (struct sockaddr*)&from,&len)) == SOCKET_ERROR)
{
printf("recvfrom failed with:%d\n",WSAGetLastError());
closesocket(sockM);
closesocket(sock);
WSACleanup();
return -1;
} if( strcmp(recvbuf,"QUIT") == 0 )
break;
else {
recvbuf[ret] = '\0';
printf("RECV:' %s ' FROM <%s> \n",recvbuf,inet_ntoa(from.sin_addr));
}
}
closesocket(sockM);
closesocket(sock);
WSACleanup();
return 0;
}
windows客户端
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(AF_INET,SOCK_DGRAM,0);
sockaddr_in my;
my.sin_family = AF_INET;
//my.sin_addr.S_un.S_addr = inet_addr("192.168.199.133");
my.sin_addr.S_un.S_addr=INADDR_ANY;
my.sin_port = htons(56789);
bind(sock, (sockaddr*)&my, sizeof(my));
int n = 1; // 注意, 这个n值很重要, 下面我会讲到
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&n, sizeof(n));
sockaddr_in addr;
addr.sin_addr.S_un.S_addr = inet_addr("239.255.255.239");
addr.sin_family = AF_INET;
addr.sin_port = htons(9111);
static int i = 0;
while(1)
{
char buf[100] = {0};
sprintf_s(buf, "blablablabla:%d", i++);
sendto(sock, buf, strlen(buf) + 1, 0, (sockaddr*)&addr, sizeof(sockaddr));
Sleep(500);
}
closesocket(sock);
WSACleanup();
return 0;
}
Linux服务端
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#define BUFLEN 255
/*********************************************************************
*filename: mcastserver.c
*purpose: 演示组播编程的基本步骤,组播服务器端,关键在于加入组
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-25 13:20:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
struct sockaddr_in peeraddr;
struct in_addr ia;
int sockfd;
char recmsg[BUFLEN + 1];
unsigned int socklen, n;
struct hostent *group;
struct ip_mreq mreq;
/* 创建 socket 用于UDP通讯 */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("socket creating err in udptalk\n");
exit(1);
}
/* 设置要加入组播的地址 */
bzero(&mreq, sizeof(struct ip_mreq));
if (argv[1]) {
if ((group = gethostbyname(argv[1])) == (struct hostent *) 0) {
perror("gethostbyname");
exit(errno);
}
} else {
printf
("you should give me a group address, 224.0.0.0-239.255.255.255\n");
exit(errno);
}
bcopy((void *) group->h_addr, (void *) &ia, group->h_length);
/* 设置组地址 */
bcopy(&ia, &mreq.imr_multiaddr.s_addr, sizeof(struct in_addr));
/* 设置发送组播消息的源主机的地址信息 */
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
/* 把本机加入组播地址,即本机网卡作为组播成员,只有加入组才能收到组播消息 */
if (setsockopt
(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
sizeof(struct ip_mreq)) == -1) {
perror("setsockopt");
exit(-1);
}
socklen = sizeof(struct sockaddr_in);
memset(&peeraddr, 0, socklen);
peeraddr.sin_family = AF_INET;
if (argv[2])
peeraddr.sin_port = htons(atoi(argv[2]));
else
peeraddr.sin_port = htons(7838);
if (argv[1]) {
if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {
printf("Wrong dest IP address!\n");
exit(0);
}
} else {
printf("no group address given, 224.0.0.0-239.255.255.255\n");
exit(errno);
}
/* 绑定自己的端口和IP信息到socket上 */
if (bind
(sockfd, (struct sockaddr *) &peeraddr,
sizeof(struct sockaddr_in)) == -1) {
printf("Bind error\n");
exit(0);
}
/* 循环接收网络上来的组播消息 */
for (;;) {
bzero(recmsg, BUFLEN + 1);
n = recvfrom(sockfd, recmsg, BUFLEN, 0,
(struct sockaddr *) &peeraddr, &socklen);
if (n < 0) {
printf("recvfrom err in udptalk!\n");
exit(4);
} else {
/* 成功接收到数据报 */
recmsg[n] = 0;
printf("peer:%s", recmsg);
}
}
}
Linux客户端
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFLEN 255
/*********************************************************************
*filename: mcastclient.c
*purpose: 演示组播编程的基本步骤,其实这就是一个基本的UDP客户端程序
*tidied by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-25 13:10:00
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Thanks to: Google.com
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
struct sockaddr_in peeraddr, myaddr;
int sockfd;
char recmsg[BUFLEN + 1];
unsigned int socklen;
/* 创建 socket 用于UDP通讯 */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
printf("socket creating error\n");
exit(1);
}
socklen = sizeof(struct sockaddr_in);
/* 设置对方的端口和IP信息 */
memset(&peeraddr, 0, socklen);
peeraddr.sin_family = AF_INET;
if (argv[2])
peeraddr.sin_port = htons(atoi(argv[2]));
else
peeraddr.sin_port = htons(7838);
if (argv[1]) {
/* 注意这里设置的对方地址是指组播地址,而不是对方的实际IP地址 */
if (inet_pton(AF_INET, argv[1], &peeraddr.sin_addr) <= 0) {
printf("wrong group address!\n");
exit(0);
}
} else {
printf("no group address!\n");
exit(0);
}
/* 设置自己的端口和IP信息 */
memset(&myaddr, 0, socklen);
myaddr.sin_family = AF_INET;
if (argv[4])
myaddr.sin_port = htons(atoi(argv[4]));
else
myaddr.sin_port = htons(23456);
if (argv[3]) {
if (inet_pton(AF_INET, argv[3], &myaddr.sin_addr) <= 0) {
printf("self ip address error!\n");
exit(0);
}
} else
myaddr.sin_addr.s_addr = INADDR_ANY;
/* 绑定自己的端口和IP信息到socket上 */
if (bind
(sockfd, (struct sockaddr *) &myaddr,
sizeof(struct sockaddr_in)) == -1) {
printf("Bind error\n");
exit(0);
}
/* 循环接受用户输入的消息发送组播消息 */
for (;;) {
/* 接受用户输入 */
bzero(recmsg, BUFLEN + 1);
if (fgets(recmsg, BUFLEN, stdin) == (char *) EOF)
exit(0);
/* 发送消息 */
if (sendto
(sockfd, recmsg, strlen(recmsg), 0,
(struct sockaddr *) &peeraddr,
sizeof(struct sockaddr_in)) < 0) {
printf("sendto error!\n");
exit(3);
}
printf("'%s' send ok\n", recmsg);
}
}
windows收发可用,linux发可用,收每隔一段时间收到一堆包,不能实时接收,可能是防火墙之类的问题。
JAVA 版客户端
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class SocketClient {
public static void main(String[] args)
{
int port=9111;
String host="239.255.255.239";
// String data ="{\"REMOTEHMI\":{\"type\":\"requestConnection\",\"IP\":\"10.173.189.37\",\"port\":57527,\"deviceName\":\"SM-G9350\",\"uuid\":\"c0a303c1-efb8-45cb-a159-cd0143e368a8\",\"oem\":\"audi\"}}";
String data="Hello world";
while(true)
{
try
{
InetAddress ip = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(data.getBytes(),data.length(),ip,port);
MulticastSocket ms = new MulticastSocket(55665);
InetAddress LoaclIp = InetAddress.getByName("192.168.199.133");
ms.setInterface(LoaclIp);
ms.setLoopbackMode(false);
ms.joinGroup(ip);
ms.setTimeToLive(1);
ms.send(packet);
System.out.println("I have send it");
ms.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
InetAddress LoaclIp = InetAddress.getByName("192.168.199.133");
ms.setInterface(LoaclIp);
这两行一定要加上,我在真机测试时,发现无线网卡没有多播包,调查好久才知道,VC和java对默认网卡选择上不一样
vc默认ipconfig的第一个网卡,JAVA默认控制面板网络连接第一个,正好是一个虚拟网卡,所以没有抓到包。