-2

i am setting up a web server in c++. I need to return from server a feature vector in the form of vector. I see that the socket doesn't allow such object to pass through directly, but need to serialize it. I am trying to serialize it by converting my vector result to a char* a. but when i do curl request, it still get back nothing. Would anyone let me know the trick here?

/* A simple server in the internet domain using TCP
The port number is passed as an argument */
// server.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <vector>
#include <iostream>

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno;
 socklen_t clilen;
 char buffer[256];
 struct sockaddr_in serv_addr, cli_addr;
 int n;
 if (argc < 2) {
     fprintf(stderr,"ERROR, no port provided\n");
     exit(1);
 }
 sockfd = socket(AF_INET, SOCK_STREAM, 0);
 if (sockfd < 0) 
    error("ERROR opening socket");
 bzero((char *) &serv_addr, sizeof(serv_addr));
 portno = atoi(argv[1]);
 serv_addr.sin_family = AF_INET;
 serv_addr.sin_addr.s_addr = INADDR_ANY;
 serv_addr.sin_port = htons(portno);
 if (bind(sockfd, (struct sockaddr *) &serv_addr,
          sizeof(serv_addr)) < 0) 
          error("ERROR on binding");
 listen(sockfd,5);
 while (1 == 1) {
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
     bzero(buffer,256);
     n = read(newsockfd,buffer,255);
     if (n < 0) error("ERROR reading from socket");
     printf("before result: %s\n",buffer);

     std::vector<float> fv;
     fv.push_back(7);
     fv.push_back(8); 
     char* result = reinterpret_cast<char*>(&fv);
     send(newsockfd, result, sizeof(result), 0);

     //n = write(newsockfd,"I got your message",18);
     //if (n < 0) error("ERROR writing to socket");
     printf("message sent. \n");
     close(newsockfd);
     //close(sockfd);
 }
 return 0; 
}

To compile the code:

g++ -o server server.cpp

And run:

 ./server 8080

For curl request:

curl http://localhost:8080

And i get:

alliey:socket alliey$ curl http://localhost:8080
`N�.

How should i interpret the response?

ayy
  • 139
  • 2
  • 9
  • 1) "_I see that the socket doesn't allow such object to pass through directly, but need to serialize it._" `(char*) &result;` is **not** a serialization of `std::vector`. 2) `sizeof(a)` in `send(newsockfd, a, sizeof(a), 0);` is equivalent to `sizeof(char*)`, and I doubt you had this in mind. 3) Consider learning from [good C++ books](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead of coding randomly. There are many fundamental misunderstandings of the language, and its concepts, in your example. – Algirdas Preidžius Jan 10 '18 at 22:12
  • You could pass every element from that vector over the network then reconstruct it if you want an quick and dirty solution – sergiu reznicencu Jan 10 '18 at 22:15
  • @AlgirdasPreidžius thanks, then how should I correctly serialize it? – ayy Jan 10 '18 at 22:15
  • Is that all the vector will hold: 7 and 8? You could use a char array and then pass its pointer to the write function. – sergiu reznicencu Jan 10 '18 at 22:17
  • @sergiureznicencu so should i do a memcpy of vector to char array? – ayy Jan 10 '18 at 22:21
  • You don't quite want to do that. Do you really need a vector in the first place? Can you use an array instead? Because an array can be passed very easily over wire while a vector object can not(that easily) – sergiu reznicencu Jan 10 '18 at 22:23
  • 1
    One way to serialize is to format to a `std::stringstream`. You could also find a library for writing JSON or XML. – Barmar Jan 10 '18 at 22:23
  • @sergiureznicencu sure i don't neccesarily need a vector float. But when i do: char* result [] = {"7","8"}; then send(newsockfd, result, sizeof(result), 0); and curl response is not readable: h�6j�6. In this case, you know how to interpret the response? – ayy Jan 10 '18 at 22:48
  • char *result[] is a two dimensional array(kind of). In your code 7 and 8 were numbers not strings. You must pass the array to the send. e.g: char numbers[]={7,8}; send(newsockfd, result, sizeof(result), 0); – sergiu reznicencu Jan 10 '18 at 22:53
  • @sergiureznicencu the socket won't send the char array in this case. curl response is empty.. it has to be char*. – ayy Jan 10 '18 at 22:56
  • char* is called pointer. num ,where char num[]={}, is a pointer. It should work. You are passing an array to the send function which reads the memory pointed to by "num" and reads some specified number of bytes – sergiu reznicencu Jan 10 '18 at 22:57
  • @sergiureznicencu ok, but curl response is empty.. – ayy Jan 10 '18 at 22:59
  • @Barmar thanks, is there any example code you know? i only find documentation.. – ayy Jan 10 '18 at 22:59
  • https://stackoverflow.com/questions/23132621/create-a-json-array-in-c – Barmar Jan 10 '18 at 23:09
  • @Barmar this is about json. i meant to ask how to send the json? – ayy Jan 10 '18 at 23:47
  • I assume the `json` class provides a method to convert to a `std::string` – Barmar Jan 11 '18 at 00:00

1 Answers1

0

i figure it out, by simply send raw data:

send(newsockfd, result.data(), sizeof(result[0])*result.size(), 0);

On the client side, i used python struck.unpack to receive the result. It works pretty well.

But still thanks for all the tips above!

ayy
  • 139
  • 2
  • 9