[英]How to send UDP datagrams from Windows PC to Raspberry Pi in C++
[英]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.