2015-04-04 31 views
0

这是我第一次问一个问题,并且第一次通过搜索这个网站找不到答案。所以如果我做错了,请对我轻松点。 使用Winsock。我需要向运行相同程序的另一台计算机发送并接收信息包。连接类型应该是UDP(非阻塞我猜?)并使用数据耦合模型。 我需要使用不同的线程发送和接收信息吗? 我知道数据发送很好,但根本没有收到。sendto和recvfrom在同一个程序中?

我可以很容易地在程序发送和一个完全不同的程序recv,但它似乎原则不会继续到我想要做的。

我应该为recvfrom和sendto使用相同的sockaddr_in结构吗?或者他们可以使用同一个吗?斯伦呢?无所谓我已经尝试过两个都没有工作。我尝试使用一个端口发送和一个接收,我已经尝试有一个端口来做到这一点。没有。对于Winsock,我相对比较陌生,如果我听起来无可救药,或者错过了一些非常明显的东西,我会很抱歉。在这一点上,我真的需要一些帮助,或者至少有一点是正确的方向我不关心有多少端口我只想看到recv printf与正确的数据传入。

的Winsock错误 绑定失败10048和recv失败10022

我也会提我看着通过MSDN提出一个概念叫setsockopt的,但它只是结束了我的进一步混乱。我错过了什么吗?

这里有一些相关的功能。

void UDPNetwork::initserver() 
{ 
    initRemote(); 
    slen2= sizeof(si_other); 
    if ((_recvSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) 
    { 
     printf("failed to create socket: %d", WSAGetLastError()); 
    } 

    _recvSocket = (AF_INET, SOCK_DGRAM, 0); 
    memset((char *)&server, 0, sizeof(server)); 

    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(PORT); 

    if (bind(_recvSocket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) 
    { 
     printf("Bind failed with error code : %d", 
      WSAGetLastError()); 
    /* system("PAUSE"); 
      exit(EXIT_FAILURE);*/ 

    } 
} 

void UDPNetwork::initclient(){ 

    slen = sizeof(si_other); 
    _sendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    if (_sendSocket == SOCKET_ERROR) 
    { 
     printf("failed to create socket... "); 
     exit(EXIT_FAILURE); 
    } 

    memset((char *)&si_other, 0, sizeof(si_other)); 
    si_other.sin_family = AF_INET; 
    si_other.sin_port = htons(PORT); 
    si_other.sin_addr.S_un.S_addr = inet_addr(SERVER); 

} 

void UDPNetwork::send(float x, float y, float z) 
{ 
    sprintf(bufOut,"%f,%f,%f", x, y, z); 
    if (sendto(_sendSocket, bufOut, strlen(bufOut), 0, (struct sockaddr*) &si_other, slen) == SOCKET_ERROR) 
    { 
     printf("sento() failed with error code : d%", WSAGetLastError()); 
     exit(EXIT_FAILURE); 
    } 
    //printf("Sent: %s\n", bufOut); 

} 

void UDPNetwork::recv(char *msg) 
{ 
    float ax = 0; float ay = 0; float az = 0; 
    memset(msg, '\0', BUFLEN); 
    recv_len = recvfrom(_recvSocket, msg, BUFLEN, 0, (struct sockaddr*) &si_other, &slen); 


    int nError = WSAGetLastError(); 
    if (nError != WSAEWOULDBLOCK&&nError != 0); 
    { 
      printf("Recv failed with error code : %d", 
     WSAGetLastError()); 
     //system("PAUSE"); 
     //exit(EXIT_FAILURE); 
    } 
    recv = buf; 
    sscanf_s(msg, "'%f,%f,%f", &ax,&ay,&az); 
    printf("RECV: %f %f %f\n", ax, ay, az); 

} 
+1

这段代码应该做什么:_'_recvSocket =(AF_INET,SOCK_DGRAM,0);'_? – 2015-04-04 07:26:50

+0

错误是['WSAEADDRINUSE'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEADDRINUSE)和['WSAEINVAL'] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668%28v=vs.85%29.aspx#WSAEINVAL)。使用['bind'](https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550%28v=vs.85%29.aspx)和['recv']一起阅读它们(https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121%28v=vs.85%29.aspx)函数引用可能是一个好的开始。 – 2015-04-04 07:30:50

+0

是的,这是MSDN让我看看setsockopt的地方,但我不知道为什么或者我该怎么处理它。有大约50个不同的插座选项。我似乎无法找到如何甚至在MSDN上使用它的很好的参考(如在一个例子中)。 setsockopt真的是实现数据耦合模型的唯一方法吗? – Mac 2015-04-04 07:41:38

回答

1

大多数UDP接收器将发送数据回到相同的IP:发送reeived数据的端口。因此,通过创建两个不同的套接字,您使用两个不同的IP:端口对,这可能是您没有收到数据的原因。数据很可能会发送到不同的IP:端口,而不是您正在阅读的端口。

对于UDP,您通常不需要创建单独的发送和接收套接字。您可以创建一个UDP套接字并将其用于发送和接收,因此发送的IP:端口与接收的IP:端口匹配。唯一需要创建单独套接字的时间是接收方有意将其数据发送到不同的IP:端口,而不是发送套接字使用的端口。

相关问题