请教UDP发送函数sendto()的使用问题

dos5gw 2010-07-12 10:25:26
原型

int PASCAL FAR sendto( SOCKET s, const char FAR* buf, int len, int flags,
const struct sockaddr FAR* to, int tolen);

看了msdn上的解释,有些地方仍不详细

如果写一个发送方程序,向多个ip发送数据,是不是只创建一个套接字,然后使用这一个套接字sendto多个目标ip? 可能描述的不是很清楚, 代码如下:

SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN remoteAddr_1; //对端ip,
//..此处创建多个SOCKADDR_IN,都放入AddrStruct结构体,此处省略

//开始向多个ip发送,sendto()的第一个参数都是同一个sockClient,第五个参数ip不同,(或者每次向不同ip send都要创建一个套接字??)
for(int remoteNum= AddrStruct.getSize(); remoteNum>=0; remoteNum--)
{

sendto(sockClient,sendBuf,strlen(senBuf)+1,0,(SOCKADDR*)&(AddrStruct.getAt(remoteNum)),len);

}


...全文
1050 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
dos5gw 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 chenlycly 的回复:]

由于是公司的代码,所以不遍透露过多~呵呵
[/Quote]
由于连贯性, 还是发在这个帖子里了, 分数的话, 可以另开传送门

我用的是2楼的方法,完全ok,只是不能往其他子网发消息,比如发送端是192.168.1.19, 所有192.168.1.*的都能收到消息,但是192.168.3.*的就没辙了

仔细比较了一下2楼。7楼的代码。
区别就是7楼往sendto的buff里填充了一个结构体CommunicateHeader,然后再把消息填充进buff里,这样sendto就能发消息到不同的子网了?
dos5gw 2010-07-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 chenlycly 的回复:]

由于是公司的代码,所以不遍透露过多~呵呵
[/Quote]

3ks to ls
dvlinker 2010-07-19
  • 打赏
  • 举报
回复
由于是公司的代码,所以不遍透露过多~呵呵
dvlinker 2010-07-19
  • 打赏
  • 举报
回复

// 命令请求及应答数据头
struct CommunicateHeader
{
unsigned leadByte; // 前导
unsigned char version; // 协议版本
unsigned char flag; // 请求(0)or应答(1)
unsigned short sequense; // 序号
unsigned dataLength; // 数据长度
unsigned cmmand; // 命令
unsigned result; // 应答结果
};
FireBirdCN 2010-07-16
  • 打赏
  • 举报
回复
[Quote=引用楼主 dos5gw 的回复:]
原型

C/C++ code

int PASCAL FAR sendto( SOCKET s, const char FAR* buf, int len, int flags,
const struct sockaddr FAR* to, int tolen);


看了msdn上的解释,有些地方仍不详细

如果写一个发送方程序,向多个ip发送数据,是不是只创建一个套接字……
[/Quote]

一个套接字即可
hyf699 2010-07-16
  • 打赏
  • 举报
回复
广播 即可
dos5gw 2010-07-14
  • 打赏
  • 举报
回复
3ks to chenlycly:
请问你的这种方式是不是可以满足不同的子网消息?
CommunicateHeader

and, 请问你代码中的nvspchecksum()以及CommunicateHeader 的定义是什么? 能不能贴以下完成的代码? 谢谢!
dvlinker 2010-07-13
  • 打赏
  • 举报
回复
不好意思,上面的代码有点小问题,重新改了一下:

sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_addr.s_addr = INADDR_BROADCAST; //广播地址
sendAddr.sin_port = htons(SDP_SERVER_PORT);

//组包头
CommunicateHeader header;

memset(&header, 0, sizeof(CommunicateHeader));
memcpy(&header.leadByte, "NVSP", sizeof(header.leadByte));
header.version = 0;
header.flag = 0;
header.sequense = 0;
header.dataLength =0;
header.cmmand = NVSP_UDP_DEVICE;
header.result = 0;

UINT iCheckSum = nvspchecksum((UCHAR*)(&header), sizeof(CommunicateHeader));

SOCKET sendSocket = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP socket
if(INVALID_SOCKET == sendSocket)
{
AfxMessageBox(_T("创建SOCKET失败!"));
return;
}

BOOL optval;
long lRet=setsockopt(sendSocket, SOL_SOCKET, SO_BROADCAST, (LPSTR)&optval, sizeof(optval));//设定为广播形式
if(-1 == lRet)
{
AfxMessageBox(_T("SOCKET选项设置失败!"));
return;
}

UINT bufferSize = sizeof(CommunicateHeader) + 4;
char* sendPacket = new char[bufferSize];
memcpy(sendPacket, &header, sizeof(CommunicateHeader));
memcpy(sendPacket + sizeof(CommunicateHeader), &iCheckSum, sizeof(iCheckSum));

long lBytesSend = sendto(sendSocket, (char*)sendPacket, bufferSize, 0, (LPSOCKADDR)&sendAddr,sizeof(sendAddr));
if (lBytesSend != bufferSize)
{
AfxMessageBox(_T("发送数据失败!"));
return -1;
}
delete []sendPacket;
dvlinker 2010-07-13
  • 打赏
  • 举报
回复
给你一段简单处理的代码,你参考一下:
        sockaddr_in sendAddr;
sendAddr.sin_family = AF_INET;
sendAddr.sin_addr.s_addr = INADDR_BROADCAST;
sendAddr.sin_port = htons(SDP_SERVER_PORT);

//组包头
CommunicateHeader header;

memset(&header, 0, sizeof(CommunicateHeader));
memcpy(&header.leadByte, "NVSP", sizeof(header.leadByte));
header.version = 0;
header.flag = 0;
header.sequense = 0;
header.dataLength =0;
header.cmmand = NVSP_UDP_DEVICE;
header.result = 0;

UINT iCheckSum = nvspchecksum((UCHAR*)(&header), sizeof(CommunicateHeader));

SOCKET sendSocket = socket(AF_INET, SOCK_DGRAM, 0);
if(INVALID_SOCKET == m_sdpSendSocket)
{
AfxMessageBox(_T("创建SOCKET失败!"));
return;
}

BOOL optval;
lRet=setsockopt(sendSocket, SOL_SOCKET, SO_BROADCAST, (LPSTR)&optval, sizeof(optval));//设定为广播形式
if(-1==lRet)
{
AfxMessageBox(_T("SOCKET选项设置失败!"));
return;
}

UINT bufferSize = sizeof(CommunicateHeader) + 4;
char* sendPacket = new char[bufferSize];
memcpy(sendPacket, &header, sizeof(CommunicateHeader));
memcpy(sendPacket + sizeof(CommunicateHeader), &iCheckSum, sizeof(iCheckSum));

long lBytesSend = sendto(sendSocket, (char*)sendPacket, bufferSize, 0, (LPSOCKADDR)&sendAddr,sizeof(sendAddr));
if (lBytesSend != bufferSize)
{
AfxMessageBox(_T("发送数据失败!"));
return -1;
}
delete []sendPacket;
飞檐走壁 2010-07-13
  • 打赏
  • 举报
回复
学习。
m_tornado 2010-07-13
  • 打赏
  • 举报
回复
要是同子网的,广播就ok了,如果是好几个不同的子网,你的法子倒也不错~
dvlinker 2010-07-12
  • 打赏
  • 举报
回复
关注中,明天给出参考代码...
Eleven 2010-07-12
  • 打赏
  • 举报
回复
sendto的第5个参数,就是你要发送的对方的IP,Port等信息。。。
来灵 2010-07-12
  • 打赏
  • 举报
回复

SOCKET s = ::socket(AF_INET, SOCK_DGRAM, 0);
// 有效SO_BROADCAST选项
BOOL bBroadcast = TRUE;
::setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(BOOL));

// 设置广播地址,这里的广播端口号(电台)是4567
SOCKADDR_IN bcast;
bcast.sin_family = AF_INET;
bcast.sin_addr.s_addr = ::inet_addr("255.255.255.255");
bcast.sin_port = htons(4567);

// 发送广播
char sz[] = "This is just a test. \r\n";
while(TRUE)
{
::sendto(s, sz, strlen(sz), 0, (sockaddr*)&bcast, sizeof(bcast));
::Sleep(5000);
}


来源:《Windows网络与通信程序设计》第5章
healer_kx 2010-07-12
  • 打赏
  • 举报
回复
你广播,/多播即可。你找找这部分的内容。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧