簡體   English   中英

C ++使用UDP發送數據報

[英]C++ Sending datagrams with 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;
    }

您總是試圖接收64個字節,但要根據echolen檢查返回值。 echolen的值是長度message ,可能不完全是64個字節。 您也沒有檢查recvfrom返回的所有可能條件。 如果返回0,則連接被另一端關閉;如果返回-1,則發生錯誤,並且其他任何值都是接收到的字節數。

注意數據報套接字是基於消息的。 如果您嘗試讀取64個字節,並且消息的長度更大,則數據報中所有未讀取的字節將被丟棄。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM