TCP server message extra characters c++












-2














I think I am missing something and doesn't make sense.



I am writing pretty simple TCP server, everything works pretty much as expected, but when a message saying "500 LOGIN FAILED" gets send over network, it get interpreted as "$500 LOGIN FAILED".




I am testing my server using telnet on localhost




here is simplified version of my code



recv(c_sockfd, buf, BUFFSIZE, 0))
inBuffer.push_back(buf);
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


in the checkResponse func, I am implementing logic to decide what message to send, and somehow when I send ERROR message the extra character is added at the beginning of the message.




EXAMPLE 1:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
674rn
202 OK
INFO iasdijasdjiajsdiajdijasidjiansdjsdvhdf dfvsdfsdfrn
&501 SYNTAX ERROR


Notice the "&" character




EXAMPLE 2:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
456rn
$500 LOGIN FAILED


Notice the "$" character



Does anyone have any idea where the extra characters could be added to the string?



I didn't want to include full code, because the requirement was to have all in one file, which makes it difficult to read. Here it goes tho.



FULL CODE:



#include <iostream>
#include <regex>
#include <iterator>
#include <vector>
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <tuple>

#define MIN_PORT 3000
#define MAX_PORT 3999
#define BUFFSIZE 1000
/**
0 - LOGIN SUCCESSFUL, USERNAME IS IN THE BUFFER
1 - PASSWORD CHECK
2 - PASSWORD OK, COMMUNICATING
*/
int state = 0;
std::string username, password;
/**
CHECKS ENTERED PASSWORD BASES ON THE SUM OF ASCII VALUES OF USERNAME
@return: true on success, false otherwise
*/
bool checkPassword(std::string password){
std::istringstream sst;
sst.str(username);
unsigned char byte = '';
int value = 0;
// std::cout << "byte poprve: " << byte << std::endl;
// std::cout << "byte poprve INT: " << (int) byte << std::endl;

while (sst >> byte) {
std::cout << "podruhe: " << byte << std::endl;
std::cout << "podruhe INT: " << (int) byte << std::endl;
std::cout << "Prubezna SUMA: " << (int) value << std::endl;
value += byte;
}
std::cout << "suma: " << value << std::endl;
// Check the entered password
if (password == std::to_string(value)) {
return true;
}

return false;
}
/**
CHECKS MESSAGE SYNTAX BASED ON THE STATE WE ARE IN
CHECKS PASSWORD
CHECKS CHECK SUM
@param response <string type (if available), string message to parse>
@return TRUE on success, FALSE otherwise
*/
bool checkMessage(std::tuple<std::string,std::string> response){

auto messageToParse = std::get<1>(response);
std::string delimeter = "rn";
std::string::size_type pos = messageToParse.find(delimeter);
//INITIAL CHECK
if (pos < 1){
return false;
}
//somehow you have to multiply the length by 2
auto parsedMessage = messageToParse.substr(0,pos - 2*delimeter.length());
std::cout << parsedMessage << " : THIS IS YOUR PARSED MESSAGE";

//USERNAME
if (state == 0) {
username = parsedMessage;
return true;
}

//PASSWORD CHECK
if (state == 1 && checkPassword(parsedMessage)) {
password = parsedMessage;
return true;
}

if (state == 2) {
std::string type = std::get<0>(response);

//INFO
if( type == "I" ){
return true;
}
//PHOTO
if ( type == "F") {
return true;
}

}

return false;
}
/**
THIS FUNC WILL CHECK RESPONSE FROM THE ROBOT, AND DECIDE WHAT TO DO BASED ON THE STATE
@return tuple<bool TRUE if everything is right,std::string MESSAGE to send to the robot>
*/
std::tuple<bool,std::string> checkResponse(std::tuple<std::string, std::string> response){

if (state == 0) {
if (checkMessage(response)) {
std::cout << state << " / / state" << std::endl;
return std::make_tuple(true, "201 PASSWORDrn");
}
}
if (state == 1) {
// TADY BUDE JESTE PODMINKA, ZE HESLO JE SPRAVNE
if(checkMessage(response)){
std::cout << state << " / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / state" << std::endl;
return std::make_tuple(false, "500 LOGIN FAILEDrn");
}
}
if (state == 2) {

if (checkMessage(response)) {
std::cout << state << " / / / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / / / state" << std::endl;
return std::make_tuple(false, "501 SYNTAX ERROR rn");
}
}
std::cout << state << " / / / / / / / / state" << std::endl;
return std::make_tuple(false, "unexpected result");
}
/**
This func will parse the incoming buffer
@param buffer incoming buffer
@return tuple <String type of message (U,I,P,F), String actual message>
*/
std::tuple<std::string, std::string> parseBuffer(std::string buffer){
if (state == 0) {
return std::make_tuple("U", buffer);
}
if (state == 1) {
return std::make_tuple("P", buffer);
}else{
std::string delimeter = " ";
std::string::size_type pos = buffer.find(delimeter);
std::string type = buffer.substr(0, pos );
std::string message = buffer.erase(0, pos + delimeter.length());

return std::make_tuple(type, message);
}


}


int main(int argc, char *argv)
{
char buf[BUFFSIZE];
std::vector<std::string> outBuffer;
std::vector<std::string> inBuffer;
int sockfd, c_sockfd;
sockaddr_in my_addr, rem_addr;
socklen_t rem_addr_length;
int mlen;
const int PORT_NUM = atoi(argv[1]);

if( (PORT_NUM > MAX_PORT) || (PORT_NUM < MIN_PORT)){
perror("Port number is not acceptable");
exit(-1);
}

if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
perror("Socket nelze otevrit");
exit(-1);
}

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT_NUM);
std::cout << PORT_NUM << " PORT NUM" << std::endl;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
{
perror("Chyba v bind");
close(sockfd); exit(1);
}

if (listen(sockfd, SOMAXCONN) == -1)
{
perror("Nelze provest listen");
close(sockfd); exit(1);
}

while (1)
{
rem_addr_length=sizeof(rem_addr);
c_sockfd = accept(sockfd, (struct sockaddr*) &rem_addr, &rem_addr_length);
if ( c_sockfd == -1)
{
perror("Nelze accept");
close(sockfd); exit(1);
}
///FIRST MESSAGE
std::string ok = "200 LOGINrn";
send(c_sockfd, &ok, sizeof(std::string), 0);

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
perror("Chyba pri cteni");
else{

while (mlen)
{

///---------- MAIN PART--------------
//This is where comunication is happening
inBuffer.push_back(buf);
//Parse the buffer, check the message and
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
///---------- MAIN PART--------------
state++;
std::cout << state << " state num" << std::endl;
if (send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0) == -1)
{
perror("Chyba pri zapisu");
break;
}else{

}

std::cout << inBuffer.back() << std::endl;

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
{
perror("Chyba pri cteni");
break;
}
}

close(c_sockfd);

}
}
}









share|improve this question




















  • 1




    What's the code you are actually running? This is not a reproducible example.
    – Matthieu Brucher
    Nov 12 '18 at 10:20






  • 2




    What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
    – Some programmer dude
    Nov 12 '18 at 10:20










  • My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
    – molbdnilo
    Nov 12 '18 at 10:36












  • You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
    – molbdnilo
    Nov 12 '18 at 10:38










  • You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
    – Galik
    Nov 12 '18 at 10:40
















-2














I think I am missing something and doesn't make sense.



I am writing pretty simple TCP server, everything works pretty much as expected, but when a message saying "500 LOGIN FAILED" gets send over network, it get interpreted as "$500 LOGIN FAILED".




I am testing my server using telnet on localhost




here is simplified version of my code



recv(c_sockfd, buf, BUFFSIZE, 0))
inBuffer.push_back(buf);
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


in the checkResponse func, I am implementing logic to decide what message to send, and somehow when I send ERROR message the extra character is added at the beginning of the message.




EXAMPLE 1:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
674rn
202 OK
INFO iasdijasdjiajsdiajdijasidjiansdjsdvhdf dfvsdfsdfrn
&501 SYNTAX ERROR


Notice the "&" character




EXAMPLE 2:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
456rn
$500 LOGIN FAILED


Notice the "$" character



Does anyone have any idea where the extra characters could be added to the string?



I didn't want to include full code, because the requirement was to have all in one file, which makes it difficult to read. Here it goes tho.



FULL CODE:



#include <iostream>
#include <regex>
#include <iterator>
#include <vector>
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <tuple>

#define MIN_PORT 3000
#define MAX_PORT 3999
#define BUFFSIZE 1000
/**
0 - LOGIN SUCCESSFUL, USERNAME IS IN THE BUFFER
1 - PASSWORD CHECK
2 - PASSWORD OK, COMMUNICATING
*/
int state = 0;
std::string username, password;
/**
CHECKS ENTERED PASSWORD BASES ON THE SUM OF ASCII VALUES OF USERNAME
@return: true on success, false otherwise
*/
bool checkPassword(std::string password){
std::istringstream sst;
sst.str(username);
unsigned char byte = '';
int value = 0;
// std::cout << "byte poprve: " << byte << std::endl;
// std::cout << "byte poprve INT: " << (int) byte << std::endl;

while (sst >> byte) {
std::cout << "podruhe: " << byte << std::endl;
std::cout << "podruhe INT: " << (int) byte << std::endl;
std::cout << "Prubezna SUMA: " << (int) value << std::endl;
value += byte;
}
std::cout << "suma: " << value << std::endl;
// Check the entered password
if (password == std::to_string(value)) {
return true;
}

return false;
}
/**
CHECKS MESSAGE SYNTAX BASED ON THE STATE WE ARE IN
CHECKS PASSWORD
CHECKS CHECK SUM
@param response <string type (if available), string message to parse>
@return TRUE on success, FALSE otherwise
*/
bool checkMessage(std::tuple<std::string,std::string> response){

auto messageToParse = std::get<1>(response);
std::string delimeter = "rn";
std::string::size_type pos = messageToParse.find(delimeter);
//INITIAL CHECK
if (pos < 1){
return false;
}
//somehow you have to multiply the length by 2
auto parsedMessage = messageToParse.substr(0,pos - 2*delimeter.length());
std::cout << parsedMessage << " : THIS IS YOUR PARSED MESSAGE";

//USERNAME
if (state == 0) {
username = parsedMessage;
return true;
}

//PASSWORD CHECK
if (state == 1 && checkPassword(parsedMessage)) {
password = parsedMessage;
return true;
}

if (state == 2) {
std::string type = std::get<0>(response);

//INFO
if( type == "I" ){
return true;
}
//PHOTO
if ( type == "F") {
return true;
}

}

return false;
}
/**
THIS FUNC WILL CHECK RESPONSE FROM THE ROBOT, AND DECIDE WHAT TO DO BASED ON THE STATE
@return tuple<bool TRUE if everything is right,std::string MESSAGE to send to the robot>
*/
std::tuple<bool,std::string> checkResponse(std::tuple<std::string, std::string> response){

if (state == 0) {
if (checkMessage(response)) {
std::cout << state << " / / state" << std::endl;
return std::make_tuple(true, "201 PASSWORDrn");
}
}
if (state == 1) {
// TADY BUDE JESTE PODMINKA, ZE HESLO JE SPRAVNE
if(checkMessage(response)){
std::cout << state << " / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / state" << std::endl;
return std::make_tuple(false, "500 LOGIN FAILEDrn");
}
}
if (state == 2) {

if (checkMessage(response)) {
std::cout << state << " / / / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / / / state" << std::endl;
return std::make_tuple(false, "501 SYNTAX ERROR rn");
}
}
std::cout << state << " / / / / / / / / state" << std::endl;
return std::make_tuple(false, "unexpected result");
}
/**
This func will parse the incoming buffer
@param buffer incoming buffer
@return tuple <String type of message (U,I,P,F), String actual message>
*/
std::tuple<std::string, std::string> parseBuffer(std::string buffer){
if (state == 0) {
return std::make_tuple("U", buffer);
}
if (state == 1) {
return std::make_tuple("P", buffer);
}else{
std::string delimeter = " ";
std::string::size_type pos = buffer.find(delimeter);
std::string type = buffer.substr(0, pos );
std::string message = buffer.erase(0, pos + delimeter.length());

return std::make_tuple(type, message);
}


}


int main(int argc, char *argv)
{
char buf[BUFFSIZE];
std::vector<std::string> outBuffer;
std::vector<std::string> inBuffer;
int sockfd, c_sockfd;
sockaddr_in my_addr, rem_addr;
socklen_t rem_addr_length;
int mlen;
const int PORT_NUM = atoi(argv[1]);

if( (PORT_NUM > MAX_PORT) || (PORT_NUM < MIN_PORT)){
perror("Port number is not acceptable");
exit(-1);
}

if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
perror("Socket nelze otevrit");
exit(-1);
}

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT_NUM);
std::cout << PORT_NUM << " PORT NUM" << std::endl;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
{
perror("Chyba v bind");
close(sockfd); exit(1);
}

if (listen(sockfd, SOMAXCONN) == -1)
{
perror("Nelze provest listen");
close(sockfd); exit(1);
}

while (1)
{
rem_addr_length=sizeof(rem_addr);
c_sockfd = accept(sockfd, (struct sockaddr*) &rem_addr, &rem_addr_length);
if ( c_sockfd == -1)
{
perror("Nelze accept");
close(sockfd); exit(1);
}
///FIRST MESSAGE
std::string ok = "200 LOGINrn";
send(c_sockfd, &ok, sizeof(std::string), 0);

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
perror("Chyba pri cteni");
else{

while (mlen)
{

///---------- MAIN PART--------------
//This is where comunication is happening
inBuffer.push_back(buf);
//Parse the buffer, check the message and
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
///---------- MAIN PART--------------
state++;
std::cout << state << " state num" << std::endl;
if (send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0) == -1)
{
perror("Chyba pri zapisu");
break;
}else{

}

std::cout << inBuffer.back() << std::endl;

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
{
perror("Chyba pri cteni");
break;
}
}

close(c_sockfd);

}
}
}









share|improve this question




















  • 1




    What's the code you are actually running? This is not a reproducible example.
    – Matthieu Brucher
    Nov 12 '18 at 10:20






  • 2




    What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
    – Some programmer dude
    Nov 12 '18 at 10:20










  • My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
    – molbdnilo
    Nov 12 '18 at 10:36












  • You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
    – molbdnilo
    Nov 12 '18 at 10:38










  • You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
    – Galik
    Nov 12 '18 at 10:40














-2












-2








-2







I think I am missing something and doesn't make sense.



I am writing pretty simple TCP server, everything works pretty much as expected, but when a message saying "500 LOGIN FAILED" gets send over network, it get interpreted as "$500 LOGIN FAILED".




I am testing my server using telnet on localhost




here is simplified version of my code



recv(c_sockfd, buf, BUFFSIZE, 0))
inBuffer.push_back(buf);
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


in the checkResponse func, I am implementing logic to decide what message to send, and somehow when I send ERROR message the extra character is added at the beginning of the message.




EXAMPLE 1:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
674rn
202 OK
INFO iasdijasdjiajsdiajdijasidjiansdjsdvhdf dfvsdfsdfrn
&501 SYNTAX ERROR


Notice the "&" character




EXAMPLE 2:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
456rn
$500 LOGIN FAILED


Notice the "$" character



Does anyone have any idea where the extra characters could be added to the string?



I didn't want to include full code, because the requirement was to have all in one file, which makes it difficult to read. Here it goes tho.



FULL CODE:



#include <iostream>
#include <regex>
#include <iterator>
#include <vector>
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <tuple>

#define MIN_PORT 3000
#define MAX_PORT 3999
#define BUFFSIZE 1000
/**
0 - LOGIN SUCCESSFUL, USERNAME IS IN THE BUFFER
1 - PASSWORD CHECK
2 - PASSWORD OK, COMMUNICATING
*/
int state = 0;
std::string username, password;
/**
CHECKS ENTERED PASSWORD BASES ON THE SUM OF ASCII VALUES OF USERNAME
@return: true on success, false otherwise
*/
bool checkPassword(std::string password){
std::istringstream sst;
sst.str(username);
unsigned char byte = '';
int value = 0;
// std::cout << "byte poprve: " << byte << std::endl;
// std::cout << "byte poprve INT: " << (int) byte << std::endl;

while (sst >> byte) {
std::cout << "podruhe: " << byte << std::endl;
std::cout << "podruhe INT: " << (int) byte << std::endl;
std::cout << "Prubezna SUMA: " << (int) value << std::endl;
value += byte;
}
std::cout << "suma: " << value << std::endl;
// Check the entered password
if (password == std::to_string(value)) {
return true;
}

return false;
}
/**
CHECKS MESSAGE SYNTAX BASED ON THE STATE WE ARE IN
CHECKS PASSWORD
CHECKS CHECK SUM
@param response <string type (if available), string message to parse>
@return TRUE on success, FALSE otherwise
*/
bool checkMessage(std::tuple<std::string,std::string> response){

auto messageToParse = std::get<1>(response);
std::string delimeter = "rn";
std::string::size_type pos = messageToParse.find(delimeter);
//INITIAL CHECK
if (pos < 1){
return false;
}
//somehow you have to multiply the length by 2
auto parsedMessage = messageToParse.substr(0,pos - 2*delimeter.length());
std::cout << parsedMessage << " : THIS IS YOUR PARSED MESSAGE";

//USERNAME
if (state == 0) {
username = parsedMessage;
return true;
}

//PASSWORD CHECK
if (state == 1 && checkPassword(parsedMessage)) {
password = parsedMessage;
return true;
}

if (state == 2) {
std::string type = std::get<0>(response);

//INFO
if( type == "I" ){
return true;
}
//PHOTO
if ( type == "F") {
return true;
}

}

return false;
}
/**
THIS FUNC WILL CHECK RESPONSE FROM THE ROBOT, AND DECIDE WHAT TO DO BASED ON THE STATE
@return tuple<bool TRUE if everything is right,std::string MESSAGE to send to the robot>
*/
std::tuple<bool,std::string> checkResponse(std::tuple<std::string, std::string> response){

if (state == 0) {
if (checkMessage(response)) {
std::cout << state << " / / state" << std::endl;
return std::make_tuple(true, "201 PASSWORDrn");
}
}
if (state == 1) {
// TADY BUDE JESTE PODMINKA, ZE HESLO JE SPRAVNE
if(checkMessage(response)){
std::cout << state << " / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / state" << std::endl;
return std::make_tuple(false, "500 LOGIN FAILEDrn");
}
}
if (state == 2) {

if (checkMessage(response)) {
std::cout << state << " / / / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / / / state" << std::endl;
return std::make_tuple(false, "501 SYNTAX ERROR rn");
}
}
std::cout << state << " / / / / / / / / state" << std::endl;
return std::make_tuple(false, "unexpected result");
}
/**
This func will parse the incoming buffer
@param buffer incoming buffer
@return tuple <String type of message (U,I,P,F), String actual message>
*/
std::tuple<std::string, std::string> parseBuffer(std::string buffer){
if (state == 0) {
return std::make_tuple("U", buffer);
}
if (state == 1) {
return std::make_tuple("P", buffer);
}else{
std::string delimeter = " ";
std::string::size_type pos = buffer.find(delimeter);
std::string type = buffer.substr(0, pos );
std::string message = buffer.erase(0, pos + delimeter.length());

return std::make_tuple(type, message);
}


}


int main(int argc, char *argv)
{
char buf[BUFFSIZE];
std::vector<std::string> outBuffer;
std::vector<std::string> inBuffer;
int sockfd, c_sockfd;
sockaddr_in my_addr, rem_addr;
socklen_t rem_addr_length;
int mlen;
const int PORT_NUM = atoi(argv[1]);

if( (PORT_NUM > MAX_PORT) || (PORT_NUM < MIN_PORT)){
perror("Port number is not acceptable");
exit(-1);
}

if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
perror("Socket nelze otevrit");
exit(-1);
}

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT_NUM);
std::cout << PORT_NUM << " PORT NUM" << std::endl;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
{
perror("Chyba v bind");
close(sockfd); exit(1);
}

if (listen(sockfd, SOMAXCONN) == -1)
{
perror("Nelze provest listen");
close(sockfd); exit(1);
}

while (1)
{
rem_addr_length=sizeof(rem_addr);
c_sockfd = accept(sockfd, (struct sockaddr*) &rem_addr, &rem_addr_length);
if ( c_sockfd == -1)
{
perror("Nelze accept");
close(sockfd); exit(1);
}
///FIRST MESSAGE
std::string ok = "200 LOGINrn";
send(c_sockfd, &ok, sizeof(std::string), 0);

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
perror("Chyba pri cteni");
else{

while (mlen)
{

///---------- MAIN PART--------------
//This is where comunication is happening
inBuffer.push_back(buf);
//Parse the buffer, check the message and
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
///---------- MAIN PART--------------
state++;
std::cout << state << " state num" << std::endl;
if (send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0) == -1)
{
perror("Chyba pri zapisu");
break;
}else{

}

std::cout << inBuffer.back() << std::endl;

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
{
perror("Chyba pri cteni");
break;
}
}

close(c_sockfd);

}
}
}









share|improve this question















I think I am missing something and doesn't make sense.



I am writing pretty simple TCP server, everything works pretty much as expected, but when a message saying "500 LOGIN FAILED" gets send over network, it get interpreted as "$500 LOGIN FAILED".




I am testing my server using telnet on localhost




here is simplified version of my code



recv(c_sockfd, buf, BUFFSIZE, 0))
inBuffer.push_back(buf);
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


in the checkResponse func, I am implementing logic to decide what message to send, and somehow when I send ERROR message the extra character is added at the beginning of the message.




EXAMPLE 1:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
674rn
202 OK
INFO iasdijasdjiajsdiajdijasidjiansdjsdvhdf dfvsdfsdfrn
&501 SYNTAX ERROR


Notice the "&" character




EXAMPLE 2:




Connected to localhost.
Escape character is '^]'.
200 LOGIN
Robot345rn
201 PASSWORD
456rn
$500 LOGIN FAILED


Notice the "$" character



Does anyone have any idea where the extra characters could be added to the string?



I didn't want to include full code, because the requirement was to have all in one file, which makes it difficult to read. Here it goes tho.



FULL CODE:



#include <iostream>
#include <regex>
#include <iterator>
#include <vector>
#include <sstream>
#include <string>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <tuple>

#define MIN_PORT 3000
#define MAX_PORT 3999
#define BUFFSIZE 1000
/**
0 - LOGIN SUCCESSFUL, USERNAME IS IN THE BUFFER
1 - PASSWORD CHECK
2 - PASSWORD OK, COMMUNICATING
*/
int state = 0;
std::string username, password;
/**
CHECKS ENTERED PASSWORD BASES ON THE SUM OF ASCII VALUES OF USERNAME
@return: true on success, false otherwise
*/
bool checkPassword(std::string password){
std::istringstream sst;
sst.str(username);
unsigned char byte = '';
int value = 0;
// std::cout << "byte poprve: " << byte << std::endl;
// std::cout << "byte poprve INT: " << (int) byte << std::endl;

while (sst >> byte) {
std::cout << "podruhe: " << byte << std::endl;
std::cout << "podruhe INT: " << (int) byte << std::endl;
std::cout << "Prubezna SUMA: " << (int) value << std::endl;
value += byte;
}
std::cout << "suma: " << value << std::endl;
// Check the entered password
if (password == std::to_string(value)) {
return true;
}

return false;
}
/**
CHECKS MESSAGE SYNTAX BASED ON THE STATE WE ARE IN
CHECKS PASSWORD
CHECKS CHECK SUM
@param response <string type (if available), string message to parse>
@return TRUE on success, FALSE otherwise
*/
bool checkMessage(std::tuple<std::string,std::string> response){

auto messageToParse = std::get<1>(response);
std::string delimeter = "rn";
std::string::size_type pos = messageToParse.find(delimeter);
//INITIAL CHECK
if (pos < 1){
return false;
}
//somehow you have to multiply the length by 2
auto parsedMessage = messageToParse.substr(0,pos - 2*delimeter.length());
std::cout << parsedMessage << " : THIS IS YOUR PARSED MESSAGE";

//USERNAME
if (state == 0) {
username = parsedMessage;
return true;
}

//PASSWORD CHECK
if (state == 1 && checkPassword(parsedMessage)) {
password = parsedMessage;
return true;
}

if (state == 2) {
std::string type = std::get<0>(response);

//INFO
if( type == "I" ){
return true;
}
//PHOTO
if ( type == "F") {
return true;
}

}

return false;
}
/**
THIS FUNC WILL CHECK RESPONSE FROM THE ROBOT, AND DECIDE WHAT TO DO BASED ON THE STATE
@return tuple<bool TRUE if everything is right,std::string MESSAGE to send to the robot>
*/
std::tuple<bool,std::string> checkResponse(std::tuple<std::string, std::string> response){

if (state == 0) {
if (checkMessage(response)) {
std::cout << state << " / / state" << std::endl;
return std::make_tuple(true, "201 PASSWORDrn");
}
}
if (state == 1) {
// TADY BUDE JESTE PODMINKA, ZE HESLO JE SPRAVNE
if(checkMessage(response)){
std::cout << state << " / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / state" << std::endl;
return std::make_tuple(false, "500 LOGIN FAILEDrn");
}
}
if (state == 2) {

if (checkMessage(response)) {
std::cout << state << " / / / / / state" << std::endl;
return std::make_tuple(true, "202 OKrn");
}else{
std::cout << state << " / / / / / / state" << std::endl;
return std::make_tuple(false, "501 SYNTAX ERROR rn");
}
}
std::cout << state << " / / / / / / / / state" << std::endl;
return std::make_tuple(false, "unexpected result");
}
/**
This func will parse the incoming buffer
@param buffer incoming buffer
@return tuple <String type of message (U,I,P,F), String actual message>
*/
std::tuple<std::string, std::string> parseBuffer(std::string buffer){
if (state == 0) {
return std::make_tuple("U", buffer);
}
if (state == 1) {
return std::make_tuple("P", buffer);
}else{
std::string delimeter = " ";
std::string::size_type pos = buffer.find(delimeter);
std::string type = buffer.substr(0, pos );
std::string message = buffer.erase(0, pos + delimeter.length());

return std::make_tuple(type, message);
}


}


int main(int argc, char *argv)
{
char buf[BUFFSIZE];
std::vector<std::string> outBuffer;
std::vector<std::string> inBuffer;
int sockfd, c_sockfd;
sockaddr_in my_addr, rem_addr;
socklen_t rem_addr_length;
int mlen;
const int PORT_NUM = atoi(argv[1]);

if( (PORT_NUM > MAX_PORT) || (PORT_NUM < MIN_PORT)){
perror("Port number is not acceptable");
exit(-1);
}

if ((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{
perror("Socket nelze otevrit");
exit(-1);
}

bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT_NUM);
std::cout << PORT_NUM << " PORT NUM" << std::endl;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1)
{
perror("Chyba v bind");
close(sockfd); exit(1);
}

if (listen(sockfd, SOMAXCONN) == -1)
{
perror("Nelze provest listen");
close(sockfd); exit(1);
}

while (1)
{
rem_addr_length=sizeof(rem_addr);
c_sockfd = accept(sockfd, (struct sockaddr*) &rem_addr, &rem_addr_length);
if ( c_sockfd == -1)
{
perror("Nelze accept");
close(sockfd); exit(1);
}
///FIRST MESSAGE
std::string ok = "200 LOGINrn";
send(c_sockfd, &ok, sizeof(std::string), 0);

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
perror("Chyba pri cteni");
else{

while (mlen)
{

///---------- MAIN PART--------------
//This is where comunication is happening
inBuffer.push_back(buf);
//Parse the buffer, check the message and
auto messageToSend = checkResponse(parseBuffer(inBuffer.back()));
//get the second thing in the tuple
outBuffer.push_back(std::get<1>(messageToSend));
bzero(buf, sizeof(buf));
///---------- MAIN PART--------------
state++;
std::cout << state << " state num" << std::endl;
if (send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0) == -1)
{
perror("Chyba pri zapisu");
break;
}else{

}

std::cout << inBuffer.back() << std::endl;

if ((mlen = recv(c_sockfd, buf, BUFFSIZE, 0)) == -1)
{
perror("Chyba pri cteni");
break;
}
}

close(c_sockfd);

}
}
}






c++ sockets c++11 tcp telnet






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 11:03







Yevgen Ponomarenko

















asked Nov 12 '18 at 10:18









Yevgen PonomarenkoYevgen Ponomarenko

214




214








  • 1




    What's the code you are actually running? This is not a reproducible example.
    – Matthieu Brucher
    Nov 12 '18 at 10:20






  • 2




    What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
    – Some programmer dude
    Nov 12 '18 at 10:20










  • My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
    – molbdnilo
    Nov 12 '18 at 10:36












  • You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
    – molbdnilo
    Nov 12 '18 at 10:38










  • You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
    – Galik
    Nov 12 '18 at 10:40














  • 1




    What's the code you are actually running? This is not a reproducible example.
    – Matthieu Brucher
    Nov 12 '18 at 10:20






  • 2




    What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
    – Some programmer dude
    Nov 12 '18 at 10:20










  • My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
    – molbdnilo
    Nov 12 '18 at 10:36












  • You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
    – molbdnilo
    Nov 12 '18 at 10:38










  • You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
    – Galik
    Nov 12 '18 at 10:40








1




1




What's the code you are actually running? This is not a reproducible example.
– Matthieu Brucher
Nov 12 '18 at 10:20




What's the code you are actually running? This is not a reproducible example.
– Matthieu Brucher
Nov 12 '18 at 10:20




2




2




What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
– Some programmer dude
Nov 12 '18 at 10:20




What is outBuffer? Please try to create a Minimal, Complete, and Verifiable Example to show us.
– Some programmer dude
Nov 12 '18 at 10:20












My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
– molbdnilo
Nov 12 '18 at 10:36






My spidey-sense indicates that outBuffer and inBuffer are collections of std::string.
– molbdnilo
Nov 12 '18 at 10:36














You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
– molbdnilo
Nov 12 '18 at 10:38




You're aware that TCP is a streaming protocol, and that you can receive any amount of data with recv, right?
– molbdnilo
Nov 12 '18 at 10:38












You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
– Galik
Nov 12 '18 at 10:40




You never check the return values of your functions to see how many bytes arrived, you just use the whole buffer regardless. And you never check for errors.
– Galik
Nov 12 '18 at 10:40












1 Answer
1






active

oldest

votes


















0














The problem is with this:



std::vector<std::string> outBuffer;


and this:



send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


You can't send std::string objects over the network. You must send the string it contains. Those are two very different things.



For a simple fix, do e.g.



send(c_sockfd, outBuffer.back().c_str(), outBuffer.back().length(), 0)


If you want to send the terminating null then add one to the length to send.





For more details, while implementations of std::string is allowed to optimize small strings to be contained inside the actual object, otherwise a std::string object is really nothing more than a size and a pointer to the actual string (implementations might have other members as well).



A pointer is unique to the currently running process on the host system. You can't transfer a pointer over the network. You can't even save a pointer to a file and then load it again and have it working in a new process (even if it's a process from the same program).



By sending the std::string object, all you're really sending is this pointer. So on the receiving side it have no idea what you're really sending and how it should treat that.






share|improve this answer





















  • I thought that I might run into some errors using std::string, thanks for the reply.
    – Yevgen Ponomarenko
    Nov 12 '18 at 12:22











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53260039%2ftcp-server-message-extra-characters-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














The problem is with this:



std::vector<std::string> outBuffer;


and this:



send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


You can't send std::string objects over the network. You must send the string it contains. Those are two very different things.



For a simple fix, do e.g.



send(c_sockfd, outBuffer.back().c_str(), outBuffer.back().length(), 0)


If you want to send the terminating null then add one to the length to send.





For more details, while implementations of std::string is allowed to optimize small strings to be contained inside the actual object, otherwise a std::string object is really nothing more than a size and a pointer to the actual string (implementations might have other members as well).



A pointer is unique to the currently running process on the host system. You can't transfer a pointer over the network. You can't even save a pointer to a file and then load it again and have it working in a new process (even if it's a process from the same program).



By sending the std::string object, all you're really sending is this pointer. So on the receiving side it have no idea what you're really sending and how it should treat that.






share|improve this answer





















  • I thought that I might run into some errors using std::string, thanks for the reply.
    – Yevgen Ponomarenko
    Nov 12 '18 at 12:22
















0














The problem is with this:



std::vector<std::string> outBuffer;


and this:



send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


You can't send std::string objects over the network. You must send the string it contains. Those are two very different things.



For a simple fix, do e.g.



send(c_sockfd, outBuffer.back().c_str(), outBuffer.back().length(), 0)


If you want to send the terminating null then add one to the length to send.





For more details, while implementations of std::string is allowed to optimize small strings to be contained inside the actual object, otherwise a std::string object is really nothing more than a size and a pointer to the actual string (implementations might have other members as well).



A pointer is unique to the currently running process on the host system. You can't transfer a pointer over the network. You can't even save a pointer to a file and then load it again and have it working in a new process (even if it's a process from the same program).



By sending the std::string object, all you're really sending is this pointer. So on the receiving side it have no idea what you're really sending and how it should treat that.






share|improve this answer





















  • I thought that I might run into some errors using std::string, thanks for the reply.
    – Yevgen Ponomarenko
    Nov 12 '18 at 12:22














0












0








0






The problem is with this:



std::vector<std::string> outBuffer;


and this:



send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


You can't send std::string objects over the network. You must send the string it contains. Those are two very different things.



For a simple fix, do e.g.



send(c_sockfd, outBuffer.back().c_str(), outBuffer.back().length(), 0)


If you want to send the terminating null then add one to the length to send.





For more details, while implementations of std::string is allowed to optimize small strings to be contained inside the actual object, otherwise a std::string object is really nothing more than a size and a pointer to the actual string (implementations might have other members as well).



A pointer is unique to the currently running process on the host system. You can't transfer a pointer over the network. You can't even save a pointer to a file and then load it again and have it working in a new process (even if it's a process from the same program).



By sending the std::string object, all you're really sending is this pointer. So on the receiving side it have no idea what you're really sending and how it should treat that.






share|improve this answer












The problem is with this:



std::vector<std::string> outBuffer;


and this:



send(c_sockfd, &outBuffer.back(), sizeof( outBuffer.back() ), 0)


You can't send std::string objects over the network. You must send the string it contains. Those are two very different things.



For a simple fix, do e.g.



send(c_sockfd, outBuffer.back().c_str(), outBuffer.back().length(), 0)


If you want to send the terminating null then add one to the length to send.





For more details, while implementations of std::string is allowed to optimize small strings to be contained inside the actual object, otherwise a std::string object is really nothing more than a size and a pointer to the actual string (implementations might have other members as well).



A pointer is unique to the currently running process on the host system. You can't transfer a pointer over the network. You can't even save a pointer to a file and then load it again and have it working in a new process (even if it's a process from the same program).



By sending the std::string object, all you're really sending is this pointer. So on the receiving side it have no idea what you're really sending and how it should treat that.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 '18 at 11:18









Some programmer dudeSome programmer dude

295k24249411




295k24249411












  • I thought that I might run into some errors using std::string, thanks for the reply.
    – Yevgen Ponomarenko
    Nov 12 '18 at 12:22


















  • I thought that I might run into some errors using std::string, thanks for the reply.
    – Yevgen Ponomarenko
    Nov 12 '18 at 12:22
















I thought that I might run into some errors using std::string, thanks for the reply.
– Yevgen Ponomarenko
Nov 12 '18 at 12:22




I thought that I might run into some errors using std::string, thanks for the reply.
– Yevgen Ponomarenko
Nov 12 '18 at 12:22


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53260039%2ftcp-server-message-extra-characters-c%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Full-time equivalent

Bicuculline

さくらももこ