繁体   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