绑定UDP套接字时出现问题

时间:2017-02-18 17:57:07

标签: c sockets networking udp messages

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

编辑 - 使用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;
}

Peer 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;
}

1 个答案:

答案 0 :(得分:0)

经过数小时的无聊故障排除后缩小了我的问题,我发现我的计算机(Mac)使我的程序无法接收消息。该程序第一次在大学的SSH服务器上试用。到目前为止,我已经将ssh服务器用作我的客户端 - 服务器程序的服务器,并在本地创建了客户端(对等)。在服务器上尝试两者后,它第一次工作。