回 帖 发 新 帖 刷新版面

主题:地址能否绑定?

想实现这样一种功能:
------------------------------------------------------------------

在一个项目中,创建一个套接字 SOCKET s1,s2;

分别绑定本机IP的 5000 端口 和 4000 端口 ,(随便两个不同端口)

尝试 s1 往 s2 以 UDP 方式发送数据,编译通过,测试失败。


------------------------------------------------------------------
问:是不是在同一进程空间不允许对本地IP绑定?还是有什么欠缺考虑的?

参考:在两个不同项目中,进程1 (本机IP端口1)往进程2 (也是本机IP,端口2)发送数据,编译测试通过。

回复列表 (共9个回复)

沙发

首先检测S1,S2是否成功
建议你每进行一次操作,对函数结果都要进行检测.

板凳

也就是说可以在一个进程中同时绑定一台电脑的2个端口?

+------------------------------------------------------------------------

我今天看了下网络编程原理,书中说可以绑定本地SOCKET与其他多个主机建立多个SOCKET,可以在多个

工作者线程中实现多个SOCKET,但没提到自绑定>=2的情况。我单步调试的结果是第二个socket直接跳掉

(未知),所以还是没弄清楚。

+---------------------------------------------------------------------------

不过,我本意原来想用锁定(阻塞)模式实现的多播接收发送的方法,

现在发现是很困难的,而用WSAEventSelected I/O模型就很容易实现了。但我还是希望弄明白上面的这

个问题。

3 楼

我试了一下 两个不同端口通信是可以的  
下面是我的两个程序
发送:
#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 楼

不对啊。

我编写了2个Console的程序,一个作为服务器,一个作为客户端。假设本机IP为:

192.168.0.10

在两个进程中分别绑定本机的4000端口和5000端口。一个只接收数据,一个只发送数据。在本机中测试

可以进行通信。

注意:我没有发送数据到 127.0.0.1 (没有采用环回测试)

5 楼

不过,在同一进程中测试失败...尚且不知道原因

6 楼

可以很负责的告诉你。采用socket能够在同一台计算机上的两个不同的端口上进行通信.
多播?你发送的时候要向多播地址发送。接收的时候加入多播组。

7 楼

6楼你没明白我的意思啊

你说的我知道啊,而且已经完成了。请你仔细看下我(2楼)的问题。

8 楼

也就是说可以在一个进程中同时绑定一台电脑的2个端口?
//////////////////
可以啊。
在同一进程中
send_socket with 1123 port
recv_socket with 1124 port
这时就可以了。
最简单的
在两个线程中分别进行收和发.

9 楼

[quote]不过,在同一进程中测试失败...尚且不知道原因[/quote]

一个线程只能对应一个端口  但是一个程序能有多个线程,

我来回复

您尚未登录,请登录后再回复。点此登录或注册