绑定UDP套接字的问题

绑定UDP套接字的问题

问题描述:

我目前正在处理的一个项目需要客户端通过UDP联系服务器,然后使用服务器在对等端之间建立令牌环网络。服务器收集每个客户端/对等端的IP和端口,然后将它们存储到一个数组中。这些阵列的元素然后由服务器通过网络发送回同级。对等方然后使用这些信息来互相连接而不是服务器。我在同伴之间传输和接收消息时遇到问题。使用打印语句,我可以确定地址结构包含正确的端口和地址。我可能正在处理缓冲区问题或某种时间问题。我重新配置了我的代码几次,似乎无法让它工作。任何提示在这一点上将不胜感激。绑定UDP套接字的问题

edit - 使用wireshark,我已经能够确定消息确实通过网络发送。程序在以下函数的while循环中暂停。但是,没有收到消息

//Thread function to check for messages on the socket 
void receiveMessages(int socket) { 
    long int nBytes = -1; 
    char buffer[BUFFERSIZE]; 

    //Wait to receive message from other peers 
    while (nBytes <= 0) { 
     nBytes = recvfrom(socket, buffer, BUFFERSIZE, 0, NULL, NULL); 
    } 

    //Print the message received 
    printf("%s", buffer); 
} 

主程序

// 
// runPeer.c 
// tokenRing 
// 
// Created by Bryce Hagar on 2/13/17. 
// Copyright © 2017 Bryce Hagar. All rights reserved. 
// 

#include <stdio.h> 
#include "bbpeer.h" 

int main(int argc, const char * argv[]){ 
    //Used for creating the Client-Server socket 
    int clientSocket; 

    //Create a local peer 
    Host localPeer = createHost(true, true); 
    //Get user information; update local peer 
    getUserInfo(localPeer, argc, argv); 
    //Configure socket structure with local peer info 
    configSockStruct(localPeer, INADDR_ANY, localPort); 

    //Create a remote server 
    Host remoteServer = createHost(false, false); 
    //Configure socket structure with remote server info 
    configSockStruct(remoteServer, remoteIP, remotePort); 

    //Create a socket bound to the local peer 
    clientSocket = createSocket(localPeer); 

    //Announce peer's existence to server and receive acceptance 
    announceToServer(localPeer, remoteServer, clientSocket); 

    //Create new remote peer host structure 
    Host remotePeer = getPeerInfo(clientSocket); 
    freeHost(remoteServer); 

    //Send messages to peers 
    sendMessageToPeer(clientSocket, remotePeer, localPeer); 

    //Receive messages from other peers 
    receiveMessages(clientSocket); 

    return 0; 
} 

同行ADT

// 
// bbpeer.c 
// bbpeer 
// 
// Created by Bryce Hagar on 2/16/17. 
// Copyright © 2017 Bryce Hagar. All rights reserved. 
// 

#include "bbpeer.h" 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <arpa/inet.h> 
#include <pthread.h> 


#define  BUFFERSIZE  1024 
#define  ACCEPTED  "accepted" 
#define  NEW    "new" 
#define  TEST   "test" 

int localPort, remotePort; //User input globals 
const char * remoteIP; 
pthread_t newThread; 

/* Get user input from command line */ 
void getUserInfo(Host localPeer, int argc, const char *argv[]) { 
    int j = 1; 

    //Error check for input issues 
    if (!localPeer->isPeer) { 
     printf("User input is only applicable for peers.\n"); 
     exit(EXIT_FAILURE); 
    } 

    //Get user input from command line 
    if (argc == 6) { 
     //Connecting to new token ring (server), 
     if (!strcmp(argv[1],"-new")) { 
      localPeer->newRing = true; 
      j++; 
     } 
    } 

    //Assign arguments to global variables 
    localPort = atoi(argv[j++]); 
    remoteIP = argv[j++]; 
    remotePort = atoi(argv[j]); 
} 

//Send announcement to server, and wait for acknoledgement 
void announceToServer(Host localPeer, Host remoteServer, int clientSocket) { 
    long int nBytes; //Used to send messages 
    char buffer[BUFFERSIZE]; 

    while(!localPeer->accepted){ 

     //Announce new peer message to server 
     memset(buffer, 0, BUFFERSIZE); 
     strcpy(buffer, NEW); 
     nBytes = strlen(buffer) + 1; 

     //Send message to server 
     sendto(clientSocket,buffer,nBytes,0,(struct sockaddr *)&remoteServer->sockAddr, 
       remoteServer->addr_size); 

     //Receive message from server 
     nBytes = recvfrom(clientSocket,buffer,BUFFERSIZE,0,NULL, NULL); 

     //If accepted, set flag 
     if (!strcmp(buffer, ACCEPTED)) { 
      localPeer->accepted = true; 
      printf("ACCEPTED BY SERVER\n");//(debug) 
     } 
    } 
} 

//Get info from server message to peers 
Host getPeerInfo(int clientSocket) { 
    long int numBytes = -1; 
    int port; 
    char buffer[BUFFERSIZE]; 
    char *ip; 

    //Clear buffer, wait for message from server 
    memset(buffer, 0, BUFFERSIZE); 
    while (numBytes <= 0) { 
     numBytes = recvfrom(clientSocket, buffer, BUFFERSIZE, 0, NULL, NULL); 
    } 

    //Tokenize the message into ip and port 
    ip = strtok(buffer, "\n"); 
    port = atoi(strtok(NULL, "\n")); 

    //Create a new host struct for the remote peer 
    Host remotePeer = createHost(true, false); 
    //Configure the socket structure for the new remote peer 
    configSockStruct(remotePeer, ip, port); 

    return remotePeer; 
} 

////////////////////////// Possible Error ////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////////// 
/////////// //////////////////////////////////////////////////////////////////////// 
//Send message to remote peer from local peer 
void sendMessageToPeer(int p2pSocket, Host remotePeer, Host localPeer) { 
    long int nBytes; 
    char buffer[BUFFERSIZE]; 
    bzero(buffer, BUFFERSIZE); 
    strcpy(buffer, TEST); 

    //Send "test" message 
    nBytes = strlen(buffer)+1; 

    //Send message to the socket(debug) 
     sendto(p2pSocket,buffer,nBytes,0,(struct sockaddr *)&remotePeer->sockAddr, 
      remotePeer->addr_size); 
    //Print the ip and port stored in the remote peer host (debug) 
    printf("%s:%d\n", inet_ntoa(remotePeer->sockAddr.sin_addr), 
      ntohs(remotePeer->sockAddr.sin_port)); 
} 

//Thread function to check for messages on the socket 
void receiveMessages(int socket) { 
    long int nBytes = -1; 
    char buffer[BUFFERSIZE]; 

    //Wait to receive message from other peers 
    while (nBytes <= 0) { 
     nBytes = recvfrom(socket, buffer, BUFFERSIZE, 0, NULL, NULL); 
    } 

    //Print the message received 
    printf("%s", buffer); 
} 

//////////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////////// 
////////////////////////// Possible Error ////////////////////////////////////// 

主机ADT

// 
// host.c 
// bbserver 
// 
// Created by Bryce Hagar on 2/17/17. 
// Copyright © 2017 Bryce Hagar. All rights reserved. 
// 

#include "host.h" 

/* Allocate memory for new host struct, 
assigns variables for peers and servers*/ 
Host createHost(bool isPeer, bool isLocal) { 
    Host newHost = malloc(sizeof(*newHost)); 
    newHost->addr_size = sizeof newHost->sockAddr; 
    newHost->isPeer = isPeer; 
    newHost->isLocal = isLocal; 
    if (isPeer) { 
     newHost->newRing = false; 
     newHost->hasToken = false; 
     newHost->accepted = false; 
    } 
    return newHost; 
} 

void freeHost(Host thisHost) { 
    free(thisHost); 
} 

/* Configure socket structure */ 
void configSockStruct(Host thisHost, const char *ip, int port) { 

    memset((void *) &thisHost->sockAddr, 0, (size_t)sizeof(thisHost->sockAddr)); 
    thisHost->sockAddr.sin_family = AF_INET; 
    memset(thisHost->sockAddr.sin_zero, '\0', sizeof thisHost-> 
     sockAddr.sin_zero); 
    thisHost->sockAddr.sin_port = htons(port); 

    if (!thisHost->isLocal) { 
     //Get address from functions parameters 
     struct hostent *hostptr = gethostbyname(ip); 
     memcpy((void *)&thisHost->sockAddr.sin_addr, 
      (void *)hostptr->h_addr, hostptr->h_length); 
    } 
    else { 
     thisHost->sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    } 
} 

int createSocket(Host thisHost) { 
    //Create UDP socket 
    int newSocket = socket(AF_INET, SOCK_DGRAM, 0); 
    bind(newSocket, (struct sockaddr *)&thisHost->sockAddr, 
     sizeof(thisHost->sockAddr)); 
    return newSocket; 
} 
+0

为什么你忽略'recvfrom()'错误并在它们上循环?除非您在错误发生时记录,否则调试只是一个猜测游戏。不要这样写代码。 – EJP

在徒劳的时间缩减了我的问题后,特鲁令人吃惊的是,我发现我的电脑(Mac)让我的程序收不到信息。该计划第一次在大学的SSH服务器上试用。直到现在,我已经使用ssh服务器作为客户机 - 服务器程序的服务器,并在本地创建了客户机(对等体)。在服务器上同时尝试后,它第一次运行。