主题:地址能否绑定?
星绽紫辉
[专家分:1700] 发布于 2008-05-25 19:07:00
想实现这样一种功能:
------------------------------------------------------------------
在一个项目中,创建一个套接字 SOCKET s1,s2;
分别绑定本机IP的 5000 端口 和 4000 端口 ,(随便两个不同端口)
尝试 s1 往 s2 以 UDP 方式发送数据,编译通过,测试失败。
------------------------------------------------------------------
问:是不是在同一进程空间不允许对本地IP绑定?还是有什么欠缺考虑的?
参考:在两个不同项目中,进程1 (本机IP端口1)往进程2 (也是本机IP,端口2)发送数据,编译测试通过。
回复列表 (共9个回复)
沙发
abzhang [专家分:550] 发布于 2008-05-26 14:56:00
首先检测S1,S2是否成功
建议你每进行一次操作,对函数结果都要进行检测.
板凳
星绽紫辉 [专家分:1700] 发布于 2008-05-26 18:07:00
也就是说可以在一个进程中同时绑定一台电脑的2个端口?
+------------------------------------------------------------------------
我今天看了下网络编程原理,书中说可以绑定本地SOCKET与其他多个主机建立多个SOCKET,可以在多个
工作者线程中实现多个SOCKET,但没提到自绑定>=2的情况。我单步调试的结果是第二个socket直接跳掉
(未知),所以还是没弄清楚。
+---------------------------------------------------------------------------
不过,我本意原来想用锁定(阻塞)模式实现的多播接收发送的方法,
现在发现是很困难的,而用WSAEventSelected I/O模型就很容易实现了。但我还是希望弄明白上面的这
个问题。
3 楼
我要飞飞飞 [专家分:180] 发布于 2008-05-29 21:02:00
我试了一下 两个不同端口通信是可以的
下面是我的两个程序
发送:
#pragma comment(lib,"ws2_32.lib")
#include <STDIO.H>
#include <WINSOCK2.H>
#define OFFLINE_HOST "192.168.1.101"
#define DATANUM 6
void HandleError(char*);
int main(int argc,char *argv[])
{
WSAData wsaData;
WSAStartup(WINSOCK_VERSION,&wsaData);
SOCKET sock=socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in to;
memset(&to,0,sizeof(to));
to.sin_addr.s_addr=inet_addr(OFFLINE_HOST);
to.sin_family=AF_INET;
to.sin_port=htons(9999);
char *buf="Hello!";
int res=sendto(sock,buf,DATANUM,0,(struct sockaddr*)&to,sizeof(to));
if(res==SOCKET_ERROR){
HandleError("sendto");
}
else
printf("Send out %d bytes!\n",res);
closesocket(sock);
WSACleanup();
return 0;
}
void HandleError(char *func)
{
int errCode=WSAGetLastError();
char info[65]={0};
_snprintf(info,64,"%s: %d\n",func,errCode);
printf(info);
}
接收:
#pragma comment(lib,"ws2_32.lib")
#include<STDIO.H>
#include<WINSOCK2.H>
int main()
{
WSAData wsaData;
WSAStartup(WINSOCK_VERSION,&wsaData);
SOCKET sock=socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in addr;
int len=sizeof(addr);
addr.sin_addr.s_addr=inet_addr("192.168.1.101");
addr.sin_family=AF_INET;
addr.sin_port=htons(9999);
if(bind(sock,(struct sockaddr*)&addr,len)==SOCKET_ERROR){
printf("bind:%d",WSAGetLastError());
}
//memset(&addr,0,sizeof(addr));
struct sockaddr_in raddr;
int rlen=sizeof(raddr);
char buf[120]={0};
int ret=recvfrom(sock,buf,120,0,(struct sockaddr*)&raddr,&rlen);
if(ret==SOCKET_ERROR){
printf("recv:%d\n",WSAGetLastError());
}
else
printf("recv %d byte from %s: %d\n",ret,inet_ntoa(raddr.sin_addr),raddr.sin_port);
closesocket(sock);
WSACleanup();
return 0;
}
第一个发送程序没有给套接口绑定地址,但我们知道UDP在发送数据之前系统会给它随机分配一个端口,
从后面接收程序显示的结果看,发送端的端口和接收端的端口是不同的.
4 楼
星绽紫辉 [专家分:1700] 发布于 2008-05-30 19:39:00
不对啊。
我编写了2个Console的程序,一个作为服务器,一个作为客户端。假设本机IP为:
192.168.0.10
在两个进程中分别绑定本机的4000端口和5000端口。一个只接收数据,一个只发送数据。在本机中测试
可以进行通信。
注意:我没有发送数据到 127.0.0.1 (没有采用环回测试)
5 楼
星绽紫辉 [专家分:1700] 发布于 2008-05-30 19:41:00
不过,在同一进程中测试失败...尚且不知道原因
6 楼
abzhang [专家分:550] 发布于 2008-06-03 09:09:00
可以很负责的告诉你。采用socket能够在同一台计算机上的两个不同的端口上进行通信.
多播?你发送的时候要向多播地址发送。接收的时候加入多播组。
7 楼
星绽紫辉 [专家分:1700] 发布于 2008-06-05 19:52:00
6楼你没明白我的意思啊
你说的我知道啊,而且已经完成了。请你仔细看下我(2楼)的问题。
8 楼
abzhang [专家分:550] 发布于 2008-06-07 10:06:00
也就是说可以在一个进程中同时绑定一台电脑的2个端口?
//////////////////
可以啊。
在同一进程中
send_socket with 1123 port
recv_socket with 1124 port
这时就可以了。
最简单的
在两个线程中分别进行收和发.
9 楼
我要飞飞飞 [专家分:180] 发布于 2008-06-07 19:12:00
[quote]不过,在同一进程中测试失败...尚且不知道原因[/quote]
一个线程只能对应一个端口 但是一个程序能有多个线程,
我来回复