★★★有关IP多播的跨网段发送数据问题,请高手们进来帮个忙,重金奖励,最高金额500可用分,请您吃饭!★★★

Summer1314 2004-09-01 04:21:00
●我有一多播软件,分为client和server两个程序,server启动时加入一个多播组(TTL已设为255),地址为:234.5.6.7,然后等待client向这个组发送信息。
●现有主机A和B,A和B在不同的网段里,其中B有两个网络连接L1和L2,L1的IP为:192.168.3.19,L2的IP为:192.168.4.1;A有一个连接L,IP为:192.168.3.24。
●在A和B上都运行client和server,然后发送信息,但是出现如下情况:
由A向B发送信息,B收不到;
由B向A发送信息,A收到,并显示发送方的IP为L1的IP。

问题如下:
1、为什么A发给B,B收不到,而反过来就能收到,有什么方法解决,使双方都能收到?
2、为什么B发给A,A收到信息后,显示发送者的IP是L1的IP,而不是L2的IP?
3、请将A发给B与B发给A的工作流程讲述一下,即在网络上是如何传输的?

备注:小弟一次最多给100分,如您能解决以上3个问题中的一个,再开100分的帖子,加上本帖您将得到200分;如能全部解决以上问题则另开4个帖子,您将得到500可用分;如您在哈尔滨,您可以以此为凭据来找我兑现一顿晚餐。
...全文
1119 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
whwjn 2004-09-20
  • 打赏
  • 举报
回复
mark,study
sevencat 2004-09-07
  • 打赏
  • 举报
回复
上面的上面说的是软路由
Hawk_lp 2004-09-07
  • 打赏
  • 举报
回复
up

gz... ...

songzhu 2004-09-07
  • 打赏
  • 举报
回复
转载一篇文章,楼主看看吧:
win2000路由器的配置方法
实例中,有两个不同网段,网段一为工作组 work1,IP地址分配为 10.0.0.2~10.0.0.5, 子网掩码为 255.0.0.0 ;网段二为工作组 work2,IP地址分配为 192.168.0.2~192.168.0.5, 子网掩码为 255.255.255.0 .两网段中的计算机均采用 WINDOWS 98 操作系统,网络结构为对等式网络。要实现两网段之间的互相通信,必须通过路由器转发IP数据包,我们采用了一台高性能的计算机( 奔腾三 866 处理器,256M 内存,迈拓金钻 7200 转 20G 硬盘)安装 WINDOWS 2000 SERVER ,作为两网段之间的软件路由器。

第一步,我们要明白,路由器既然是不同网段之间的存储转发设备,则其必定有多个网络接口,也就是说,其必然要安装多块网卡,才能在多个网段之间起到“桥梁”的作用。而且路由器工作在TCP/IP的网络环境中,每一块网卡都要绑定各自独立的IP地址。

在本实例中,我们要连接两个网段,则必须在 WINDOWS 2000 SERVER 中安装两块网卡,这一次所采用的是两块 TF- 3239TX 100 M 网卡(采用 REALTEK 8139 芯片,PCI 槽, RJ 45 单口).在安装WINDOWS 2000 SERVER 时,要注意的几点:1,这一台装有WINDOWS 2000 SERVER 的计算机将是独立的服务器,不必要升级为域控制器。在确定其属于哪一个工作组时,可以是work1也可是work2 . 2 ,安装网络协议时至少要安装TCP/IP 协议。2, REALTEK 8139 的网卡为即插即用的网卡,在系统找到两块网卡时,要分别安装它们的驱动,直至 "控制面板 "--“系统”--“硬件”--“设备管理器”--“网卡”下能看到两块网卡的标志,没有黄色惊叹号,设备状态是“工作正常”为止。若网卡因为硬件冲突导致工作不正常,则路由器肯定不能发挥作用。3,给每一块网卡绑定 IP 地址,一块做为work1的网络接口,绑定 10.0.0.1,(工业标准是将网络的第一个 IP 地址指派到路由器接口。)具体步骤为, "控制面板 "--“网络和拨号连接"--"本地连接”,选择“属性”--“INTERNET协议(TCP/IP)",选择“属性”,然后选择“使用下面的IP地址”填入10.0.0.1 ,子网掩码为 255.0.0.0 ,默认网关为“10.0.0.1 ”,单击“确定”.另一块网卡做为work2的网络接口,绑定192.168.0.1 ( 注意:“本地连接”对应第一块网卡,“本地连接2”对应第二块网卡,不要弄混)方法同上。我们可以在 “INTERNET协议(TCP/IP)"--“属性”对话框中点击“高级”来检验网卡的 IP地址绑定情况。

第二步,启动路由。启动路由服务有两种方法,一种是在开机时出现的“配置服务器”的选项卡中选择“联网”,在“联网”的下拉菜单下单击“路由”;另一种是单击“开始”-“程序”-“管理工具”-“路由和远程访问”,打开路由和远程访问管理器,会见到以此台计算机名命名的服务器图标。选中此台服务器,单击鼠标右键,选择“配置并启用路由和远程访问”,随后就会出现“路由和远程访问服务器安装向导”,按照提示一步一步做下去,在“公共设置”中选择“网路路由器”,接着就会选择路由的协议,协议框内至少应保证有 TCP/IP , 选中它,然后是“请求拨号连接”,当出现“您想请求拨号访问远程网络吗?”,因为我们是配置本地的静态路由,因此选择“否”,最后单击“完成”,路由服务安装完毕。

启动路由服务后,我们可以看到“路由接口”的子项 "内部“,“环回”,“本地连接”,“本地连接2”的状态均为“已启用”,连接状态均为“已连接上”,其中“本地连接”,“本地连接2”的“设备名”就是我们的网卡型号,证明这两个接口可以用来连接局域网中的两个网段。在“IP路由选择”的“常规”子项中给出了这两个接口分别各自所属的子网以及他们各自的流量统计。

在两网段其他计算机的 WINDOWS 98 系统中, 选择"控制面板"--“网络”--选择“TCP/IP-网卡类型”(本例中为 REALTEK 8139 ),单击“属性”,找到“网关”选项卡,第一个网段要添加的网关为 10.0.0.1 第一个网段要添加的网关为 192.168.0.1.

此时,路由器已初步发挥作用,可用来连接10.0.0.2~10.0.0.5, 与 192.168.0.2~192.168.0.5 两个不同网段。我们必须进行测试,具体方法为在第一网段内任选一台计算机发送数据包至第二网段内任一台计算机,并进行跟踪,观察路由器转发数据包的情况。在10.0.0.2 的计算机上的"MS-DOS方式"下键入tracert to 192.168.0.2,结果如下:

Tracing route to 192.168.0.2
  over a maximum over 5 of 30 hops :
  0 10.0.0.2
  1 10.0.0.1
  2 192.168.0.1
  3 192.168.0.2
  Trace complete

数据包成功地经过两个网络接口,到达目的地,随后两机之间再用 PING 检验,均能收到回应,证明两机之间已可互传数据,两网段连通。

实际上,由此实例推而广之,我们就可得到如何用四张网卡连接三台计算机的方法。有很多时侯,我们想用双绞线连接三台计算机,又不愿意买集线器,从节省成本的角度考虑,我们可以多买一块网卡,设一台计算机为路由器,其他两台计算机设置不同网段的IP地址,通过路由器互连。这样组建起来的对等网虽然对联网打游戏有一定的不便,但仍可互传文件,也可共享上网。更重要的是,可以组建 100 M 以上的快速以太网,这是用细缆互连无法实现的。

第三步,配置静态路由。若用两个路由器连接三个网段,则需告诉第一台路由器第三个网段的地址,也要告诉第三台路由器第一个网段的地址。这就是“静态路由”,具体配置方法如下。


在第一台路由器的路由管理器中,找到“IP路由选择”中的“静态路由”单击鼠标
右键,打开“静态路由”添加对话框,找到 10.0.0.1 的网络接口,(在本例中是"本地连接",然后键入第三个网段的网络号,即在“目标”中键入172.16.0.0( 注意:这是网络号,不是主机IP地址,因此最后一位是 0 )网络掩码为 255.255.0.0

网关为 172.16.0.1 同理,在第三台路由器中也要找到172.16.0.1 的网络接口,添加 “目标”为 10.0.0.0 网络掩码为 255.0.0.0 , 网关为 10.0.0.1 的 静态路由。添加方法同上。

由此可见,静态路由需要管理员事先规划好网络路径,并且要手动更新路由表。因此静态路由不适用于大型网络,仅在小规模的局域网中发挥作用。

最后说明一点,若网络的类型为 客户机/服务器 网,路由器要加入到域中,以便管理员通过域控制器实施统一管理。
cai3995 2004-09-06
  • 打赏
  • 举报
回复
Use the "netsh" and "routing" command to config the router mode for microsoft Windows
Summer1314 2004-09-06
  • 打赏
  • 举报
回复
To songzhu():
B有两个网络连接意思是有两块网卡。
我在测试时用一台主机当路由器,不知道该如何配置主机变成路由器,能教教我吗?
oyljerry 2004-09-06
  • 打赏
  • 举报
回复
在主机上配置成服务器,win2k就可以设置成一个简单的路由功能的服务器
songzhu 2004-09-05
  • 打赏
  • 举报
回复
你的代码没有问题,我运行过了,无论在一个网段内还是跨网段程序运行正常,没有你说的情况。
你说的B连两个网络是什么意思,另外,跨网段,路由器要支持组播才行。
lanjian9 2004-09-03
  • 打赏
  • 举报
回复
不通过网络设备,你认为这有可能实现吗?
oyljerry 2004-09-02
  • 打赏
  • 举报
回复
组播(Multicast)传输:它提高了数据传送效率。减少了主干网出现拥塞的可能性。
组播组中的主机可以是在同一个物理网络, 也可以来自不同的物理网络(如果有组播路由器的支持)。
因而你的实现需要配置路由器,大体上要在路由器上完成IGMP和DVMRP的配值
Summer1314 2004-09-02
  • 打赏
  • 举报
回复
回复人: sevencat(七猫) ( ) 信誉:102 2004-09-01 18:47:00 得分: 0
现在一般有硬件解决和软件解决办法,假如是IPV6就好了,IPV4一般路由都不会转发多播包,除非你自己用一些软件(LINUX和WIN)下面都有的。
--------------------------------
sevencat(七猫):请问用什么软件可以解决路由的问题(Win And Linux)?
sevencat 2004-09-02
  • 打赏
  • 举报
回复
呵呵,当时多播和IPV6我研究了一个月呢。
crazyeagle 2004-09-02
  • 打赏
  • 举报
回复
mark
sharkhuang 2004-09-02
  • 打赏
  • 举报
回复
要路由器支持.
Summer1314 2004-09-02
  • 打赏
  • 举报
回复
请问Unix网络编程这本书在哪里下载?
sevencat 2004-09-02
  • 打赏
  • 举报
回复
代码应该不会有啥问题了。
Jimmy_Xia 2004-09-02
  • 打赏
  • 举报
回复
学习!
Summer1314 2004-09-02
  • 打赏
  • 举报
回复
server代码:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib")

#define BUFSIZE 1024
#define TTL_VALUE 255
#define TIME_OUT 10000
#define TEST_ADDR "234.5.6.7"
#define TEST_PORT 9200
#define LOOPMAX 20

int main(int argc, char* argv[])
{
struct sockaddr_in stlocal, stfrom;
char achin[BUFSIZE];
struct ip_mreq stmrep;
WSADATA stwsa;
SOCKET s;
int i, itmp, iret, addr_size;

itmp = WSAStartup(MAKEWORD(2, 2), &stwsa);
if (itmp)
{
printf("Call WSAStartup failed. Return value: %d\t\n", itmp);
exit(1);
}
//创建数据报套接字
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("Call socket failed. Error number: %d\t\n", WSAGetLastError());
exit(1);
}
//设置socket属性
itmp = TRUE;
iret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&itmp, sizeof(int));
if (iret == SOCKET_ERROR)
{
printf("Call setsockopt SO_REUSEADDR failed. Error number: %d\t\n",
WSAGetLastError());
exit(1);
}
stlocal.sin_family = AF_INET;
stlocal.sin_addr.s_addr = INADDR_ANY;
stlocal.sin_port = htons(TEST_PORT);
iret = bind(s, (struct sockaddr *)&stlocal, sizeof(stlocal));
if (iret == SOCKET_ERROR)
{
printf("Call bind failed. Error number: %d\t\n", WSAGetLastError());
exit(1);
}
//加入组播组,设置参数
stmrep.imr_multiaddr.s_addr = inet_addr(TEST_ADDR);
stmrep.imr_interface.s_addr = INADDR_ANY;
iret = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stmrep, sizeof(stmrep));
if (iret == SOCKET_ERROR)
{
printf("Call setsockopt IP_ADD_MEMBERSHIP failed. Error number: %d\t\n",
WSAGetLastError());
exit(1);
}
//Set TTL to traverse up to multiple routers
itmp = TTL_VALUE;
iret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&itmp, sizeof(int));
if (iret == SOCKET_ERROR)
{
printf("Call setsockopt IP_MULTICAST_TTL failed. Error number: %d\t\n",
WSAGetLastError());
exit(1);
}
//Disable loopback
itmp = FALSE;
iret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&itmp, sizeof(int));
if (iret == SOCKET_ERROR)
{
printf("Call setsockopt IP_MULTICAST_LOOP failed. Error number: %d\t\n",
WSAGetLastError());
exit(1);
}
addr_size = sizeof(struct sockaddr_in);
for (i = 0; i < LOOPMAX; i++)
{
printf("Now receiving multicast message, address: %s\n", TEST_ADDR);
iret = recvfrom(s, achin, BUFSIZE, 0, (struct sockaddr *)&stfrom, &addr_size);
if (iret == SOCKET_ERROR)
{
printf("Call recvfrom failed. Error number: %d\t\n", WSAGetLastError());
exit(1);
}
//inet_ntoa(stFrom.sin_addr)函数将32位的IP地址转化成IP地址字符串
printf("Received from host: %s port: %d data: %s\n", inet_ntoa(stfrom.sin_addr),
ntohs(stfrom.sin_port), achin);
}

closesocket(s);
WSACleanup();

system("PAUSE");
return 0;
}


Summer1314 2004-09-02
  • 打赏
  • 举报
回复
client代码:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "WS2_32.lib")

//常量定义
#define BUFSIZE 1024
#define TTL_VALUE 255
#define TIME_OUT 2
#define TEST_ADDR "234.5.6.7"
#define TEST_PORT 9200
#define LOOPMAX 10000

int main(int argc, char* argv[])
{
struct sockaddr_in stto;
char achout[BUFSIZE]; //要发送的信息
WSADATA stwsa;
SOCKET s;
int i, itmp, iret, addr_size;

itmp = WSAStartup(MAKEWORD(2, 2), &stwsa);
if (itmp)
{
printf("Call WSAStartup failed. Return value: %d\t\n", itmp);
exit(1);
}
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
{
printf("Call socket failed. Error number: %d\t\n", WSAGetLastError());
exit(1);
}
//组播组的地址信息
stto.sin_family = AF_INET;
stto.sin_addr.s_addr = inet_addr(TEST_ADDR);
stto.sin_port = htons(TEST_PORT);
//开始发送并接收信息
addr_size = sizeof(struct sockaddr_in);
for (i = 0; i < LOOPMAX; i++)
{
printf("Input the message: ");
scanf("%s", achout);
printf("Now sending to multicast group, address: %s\n", TEST_ADDR);
iret = sendto(s, achout, sizeof(achout), 0, (struct sockaddr *)&stto, addr_size);
if (iret == SOCKET_ERROR)
{
printf("Call sendto failed. Error number: %d\t\n", WSAGetLastError());
exit(1);
}
}

closesocket(s);
WSACleanup();

system("PAUSE");
return 0;
}

yening0914 2004-09-02
  • 打赏
  • 举报
回复
如果想接收多播数据,必须加入组。如果只打算发送数据,不必加入一个IP多播组!
加载更多回复(17)

18,356

社区成员

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

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