C ++使用UDP发送数据报

时间:2013-04-25 02:55:05

标签: c++ udp

再次问好stackoverflow!

我让我的教授为我分配了一个程序,该程序会尝试接收用户输入的信用卡信息,将数据库中的数据库发送到服务器并打印返回的内容。

我想我差不多完成了,但是当我尝试将信息发送到服务器时,我的一个错误正在消失。

恐怖是

Mismatch in number of sent bytes: Permission Denied

我不知道该做什么,所以任何建议都会受到赞赏:) 我在下面发布了我的代码:

#include <iostream>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <cstdio>
#include <cstdlib>

using namespace std;

int countDigits(char[], int);
int findDec(char[],int);
int findLastEle(char[]);
int findSlash(char[],int);

int main() {

    //variables
    char cardNum[64], cardName[64], expDate[8], cardAmt[64], message[64]; //User input variables and datagram message

    int cardNumlen, cardDigits, amtLen, decVar, lastVar,
        expLast, expEle, expLen, sock, echolen, received = 0;
    char buffer[64];

    unsigned int addrlen;

    struct sockaddr_in echoserver;  // structure for address of server

    //Welcome the user
    cout << "Welcome to the Credit Card Transaction verification utility!\n";

    //ask user for card holder name or quit
    cout << "Enter card holder name (or quit): ";
    cin.getline(cardName, 64);

    //Make loop that will quit if quit chosen
    while(strcmp(cardName, "quit") != 0){
        //Ask for numbers
        cout << "Enter CC number: ";
        cin.getline(cardNum, 64);

        //count number of digets
        cardNumlen = strlen(cardNum);
        cardDigits = countDigits(cardNum, cardNumlen);

        //make sure there are 15-16 digits
        while(cardDigits < 15 or cardDigits > 16){
            cout << "You have entered an invalid CC number. Please try again: ";
            cin.getline(cardNum, 64);
            cardNumlen = strlen(cardNum);
            cardDigits = countDigits(cardNum, cardNumlen);
        }

        //ask for experation date
        do{
            cout << "Enter experation (form mm/yyyy): ";
            cin.getline(expDate, 8);
            expLen = strlen(expDate);
            expEle = findSlash(expDate, expLen);
            expLast = findLastEle(expDate);
        }while(expEle != (expLast - 5));

        //ask for card amount
        cout << "Enter amount: ";
        cin.getline(cardAmt, 64);

        //find . in char array
        amtLen = strlen(cardAmt);
        decVar = findDec(cardAmt, amtLen);

        //find last character in array
        lastVar = findLastEle(cardAmt);
        //Make sure . is in right spot
        while(decVar != (lastVar - 3)){

            //ask for card amount again if fail
            cout << "You entered an invalid amount! Please try again: ";
            cin.getline(cardAmt, 64);

            //find . in char array
            amtLen = strlen(cardAmt);
            decVar = findDec(cardAmt, amtLen);

            //find last character in array
            lastVar = findLastEle(cardAmt);
        }

        cout << "Verifying...\n";

        //Make the message by looping
        // through message and putting 
        // each character into message
        strcpy(message, cardNum);
        strcat(message, ":");
        strcat(message, expDate);
        strcat(message, ":");
        strcat(message, cardAmt);
        strcat(message, ":");
        strcat(message, cardName);

        // Create the UDP socket
        if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
            perror("Failed to create socket");
            exit(EXIT_FAILURE);
        }

        // Construct the server sockaddr_in structure
        memset(&echoserver, 0, sizeof(echoserver));
        echoserver.sin_family = AF_INET;                  //Internet IP
        echoserver.sin_addr.s_addr = inet_addr("IPADDRESSHERE");  //IP address
        echoserver.sin_port = htons(PORTHERE);       //server port

        // Send the message to the server 
        echolen = strlen(message);
        if (sendto(sock, message, strlen(message), 0, (struct sockaddr *) &echoserver, sizeof(echoserver)) != echolen) {
            perror("Mismatch in number of sent bytes");
            exit(EXIT_FAILURE);
        }

        // Receive the message back from the server 
        addrlen = sizeof(echoserver);
        if ((received = recvfrom(sock, buffer, 64, 0, (struct sockaddr *) &echoserver, &addrlen)) != echolen) {
            perror("Mismatch in number of received bytes");
            exit(EXIT_FAILURE);
        }

        buffer[received] = '\0';        /* Assure null-terminated string */
        cout << buffer << endl;

        close(sock); // closing the sock

        //Restart the while(maybe quit) loop
        //ask user for card holder name or quit
        cout << "\nEnter card holder name (or quit): ";
        cin.getline(cardName, 64);

    }//end of while loop for quit
    return 0;
}

这些是我为帮助获取用户输入所做的功能

    //countDigits function
    int countDigits(char array[], int strLen){
        int i, digits = 0;
        for( i = 0; i < strLen; i++){
            if( array[i] == ' '){
                digits--;
            }
            digits++;
        }
        return digits;

    }

    //findDec function (finds decimal place in array)
    int findDec(char array[], int arrayLen){
        int r, dec = 0;

        for(r = 0; r < arrayLen; r++){
            if(array[r] == '.'){
                break;
            }
            else{
                dec++;
            }
        }

        return dec;
    }

    //Finds the last element in a array
    int findLastEle(char array[]){
        int i, last;
        while(array[i]){
            i++;
            last++;
        }

        return last;
    }

    //findSlash function (finds slash place in array)
    int findSlash(char array[], int arrayLen){
        int r, dec = 0;

        for(r = 0; r < arrayLen; r++){
            if(array[r] == '/'){
                break;
            }
            else{
                dec++;
            }
        }

        return dec;
    }

1 个答案:

答案 0 :(得分:0)

您总是尝试接收64个字节,但检查echolen的返回值。 echolen中的值是长度message,可能不是64字节。您也没有检查recvfrom返回的所有可能条件。如果它返回0,则连接被另一方关闭,如果它返回-1则发生错误,任何其他值是接收的字节数。

请注意数据报套接字是基于消息的。如果您尝试读取64个字节并且消息的长度更大,则数据报中的所有未读字节都将被丢弃。