最近在写一个组播通信的功能,结果发现接受同一台电脑上只能运行一个接收端,如果运行两个时,第二个运行的程序不能收到数据。查找原因是因为没有设置端口数据复用的功能(setsockpot),setsockpot的调用见代码。
//发送端
// Send.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include<WinSock2.h>
#include <iostream>
#include <Ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_addr.S_un.S_addr = inet_addr("239.255.88.8");
sa.sin_port = htons(6868);
int count = 0;
char serr[1024] = { 0 };
int a = 0;
while (1)
{
sprintf_s(serr, "Setsock falied ! %d", count);
a = sendto(sock, serr, sizeof(serr), 0, (sockaddr*)&sa, sizeof(sa));
if (a > 0)
{
count++;
//cout << "send hello lvzai sucessful " << count << endl;
cout << serr << endl;
}
Sleep(20);
}
return 0;
}
//接收端
// Recv.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include<WinSock2.h>
#include <iostream>
#include <Ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int main()
{
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
SOCKADDR_IN addr_rec;
addr_rec.sin_family = AF_INET;
addr_rec.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr_rec.sin_port = htons(6868);
bool bOptval = true;
int iret = 0;
iret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptval, sizeof(bOptval));
if (iret != 0)
cout << "setsockopt fail: " << WSAGetLastError() << endl;
iret = bind(sock, (SOCKADDR*)&addr_rec, sizeof(addr_rec));
if (iret != 0)
{
char serr[1024] = { 0 };
sprintf_s(serr, "kbind falied ! %d", WSAGetLastError());
cout << "bind fail" << endl;
return -1;
}
struct ip_mreq mreq;
mreq.imr_interface.s_addr = htonl(INADDR_ANY);; //inet_addr("169.254.4.119");
mreq.imr_multiaddr.s_addr = inet_addr("239.255.88.8");
if (setsockopt(sock,IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) !=0)
{
char serr[1024] = { 0 };
sprintf_s(serr, "Setsock falied ! %d", WSAGetLastError());
cout << "加入组播失败!" <<serr << endl;
}
int len = sizeof(SOCKADDR);
int res = 0;
char strRecv[1024] = { 0 };
int coutt = 0;
while (1)
{
res = recvfrom(sock, strRecv, sizeof(strRecv), 0, (SOCKADDR*)&addr_rec, &len);
if (res > 0)
{
coutt++;
cout << "recv Data : " << strRecv << " coutt: " << coutt << endl;
}
}
return 0;
}
其中最关键的是setsockopt函数的使用。