2017-10-06 55 views
-3

我需要发送一个字符串回客户端,其中包括车辆和车辆的修改器(carStyling)的成本。我想返回一个包含sline和客户端成本的字符串。就像是;如何从C中返回一个字符串从服务器到客户端?

您的轿车越野将花费$ 150000。

下面的段落包含必要的代码。

#include <arpa/inet.h> 

#include <netdb.h> 

#include <netinet/in.h> 

#include <unistd.h> 

#include <iostream> 

#include <cstring> 

#include <stdlib.h> 

#include <stdio.h> 

#include <string> 

#include <sstream> 



#define MAX_MSG 100 

#define LINE_ARRAY_SIZE (MAX_MSG+1) 



using namespace std; 



int main() 

{ 

    int listenSocket, connectSocket, i; 

    unsigned short int listenPort; 

    socklen_t clientAddressLength 
; 

    struct sockaddr_in clientAddress, serverAddress; 

    char line[LINE_ARRAY_SIZE]; 





    cout << "Enter port number to listen on (between 1500 and 65000): "; 

    cin >> listenPort; 



    // Create socket for listening for client connection 

    // requests. 

    listenSocket = socket(AF_INET, SOCK_STREAM, 0); 

    if (listenSocket < 0) { 

    cerr << "cannot create listen socket"; 

    exit(1); 

    } 



    // Bind listen socket to listen port. First set various 

    // fields in the serverAddress structure, then call 

    // bind(). 



    // htonl() and htons() convert long integers and short 

    // integers (respectively) from host byte order (on x86 

    // this is Least Significant Byte first) to network byte 

    // order (Most Significant Byte first). 

    serverAddress.sin_family = AF_INET; 

    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); 

    serverAddress.sin_port = htons(listenPort); 



    if (bind(listenSocket, 

      (struct sockaddr *) &serverAddress, 

      sizeof(serverAddress)) < 0) { 

    cerr << "cannot bind socket"; 

    exit(1); 

    } 



    // Wait for connections from clients. This is a 

    // non-blocking call; i.e., it registers this program with 

    // the system as expecting connections on this socket, and 

    // then this thread of execution continues on. 

    listen(listenSocket, 5); 



    while (1) { 

    cout << "Waiting for TCP connection on port " << listenPort << " ...\n"; 



    // Accept a connection with a client that is requesting 

    // one. The accept() call is a blocking call; i.e., this 

    // thread of execution stops until a connection comes 

    // in. connectSocket is a new socket that the system 

    // provides, separate from listenSocket. We *could* 

    // accept more connections on listenSocket, before 

    // connectSocket is closed, but this program doesn't do 

    // that. 

    clientAddressLength = sizeof(clientAddress); 

    connectSocket = accept(listenSocket, 

          (struct sockaddr *) &clientAddress, 

          &clientAddressLength); 

    if (connectSocket < 0) { 

     cerr << "cannot accept connection "; 

     exit(1); 

    } 



    // Show the IP address of the client. 

    // inet_ntoa() converts an IP address from binary form to the 

    // standard "numbers and dots" notation. 

    cout << " connected to " << inet_ntoa(clientAddress.sin_addr); 



    // Show the client's port number. 

    // ntohs() converts a short int from network byte order (which is 

    // Most Significant Byte first) to host byte order (which on x86, 

    // for example, is Least Significant Byte first). 

    cout << ":" << ntohs(clientAddress.sin_port) << "\n"; 



    // Read lines from socket, using recv(), storing them in the line 

    // array. If no messages are currently available, recv() blocks 

    // until one arrives. 

    // First set line to all zeroes, so we'll know where the end of 

    // the string is. 

    memset(line, 0x0, LINE_ARRAY_SIZE); 



    while (recv(connectSocket, line, MAX_MSG, 0) > 0) { 

     cout << " -- " << line << "\n"; 



     // Convert line to upper case. 

     for (i = 0; line[i] != '\0'; i++) 

     line[i] = toupper(line[i]); 





     // creating an object to direct line to a string array 

     std::string delimiter[2]; 

     int i = 0; 

     double cost = 0; 

     std::string carType; 

     std::string carStyling; 

     std::string sline; 

     sline = line; 

     stringstream ssin(sline); 



      while (ssin.good() && i < 2){ 

      ssin >> delimiter[i]; 

      ++i; 

     } 

      for(i = 0; i < 2; i++){ 

      cout << delimiter[i] << endl; 

     } 



      if(i==0) { 

      carType = delimiter[0]; 



       if(carType.compare("SEDAN")==0){ 

       sline = "Your Sedan"; 

       cost = 100000; 

       std::copy(sline.begin(), sline.end(), line); 

       line[sline.size()] = '\0'; 

       } 

       else if(carType.compare("MPV")==0){ 

       sline = "MPV"; 

       cost = 120000; 

       std::copy(sline.begin(), sline.end(), line); 

       line[sline.size()] = '\0'; 

       } 

       else if(carType.compare("SUV")==0){ 

       sline = "SUV"; 

       cost = 140000; 

       std::copy(sline.begin(), sline.end(), line); 

       line[sline.size()] = '\0'; 

       } 

       else if(carType.compare("LUXURY")==0){ 

       sline = "LUXURY"; 

       cost = 180000; 

       std::copy(sline.begin(), sline.end(), line); 

       line[sline.size()] = '\0'; 

       } 



     if(i==2) { 

      carStyling = delimiter[1]; 



       if(carStyling.compare("SPORTY")==0){ 

       sline += "Sporty"; 

       cost = cost * 1.5; 

       } 

       else if(carStyling.compare("OFFROAD")==0){ 

       sline += "Offroad"; 

       cost = cost * 1.3; 

       } 



     } 



     } 





     // Send converted line back to client. 

     if (send(connectSocket, line, strlen(line) + 1, 0) < 0) 

     cerr << "Error: cannot send modified data"; 



     memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes 

    } 

    } 

} 

这里另一种是用于client.cc

#include <netdb.h> 

#include <netinet/in.h> 

#include <unistd.h> 

#include <iostream> 

#include <cstring> 

#include <stdlib.h> 



#define MAX_LINE 100 

#define LINE_ARRAY_SIZE (MAX_LINE+1) 



using namespace std; 



int main() 

{ 

    int socketDescriptor; 

    unsigned short int serverPort; 

    struct sockaddr_in serverAddress; 

    struct hostent *hostInfo; 

    char buf[LINE_ARRAY_SIZE], c; 



    cout << "Enter server host name or IP address: "; 

    cin.get(buf, MAX_LINE, '\n'); 



    // gethostbyname() takes a host name or ip address in "numbers and 

    // dots" notation, and returns a pointer to a hostent structure, 

    // which we'll need later. It's not important for us what this 

    // structure is actually composed of. 

    hostInfo = gethostbyname(buf); 

    if (hostInfo == NULL) { 

    cout << "problem interpreting host: " << buf << "\n"; 

    exit(1); 

    } 



    cout << "Enter server port number: "; 

    cin >> serverPort; 

    cin.get(c); // dispose of the newline 



    // Create a socket. "AF_INET" means it will use the IPv4 protocol. 

    // "SOCK_STREAM" means it will be a reliable connection (i.e., TCP; 

    // for UDP use SOCK_DGRAM), and I'm not sure what the 0 for the last 

    // parameter means, but it seems to work. 

    socketDescriptor = socket(AF_INET, SOCK_STREAM, 0); 

    if (socketDescriptor < 0) { 

    cerr << "cannot create socket\n"; 

    exit(1); 

    } 



    // Connect to server. First we have to set some fields in the 

    // serverAddress structure. The system will assign me an arbitrary 

    // local port that is not in use. 

    serverAddress.sin_family = hostInfo->h_addrtype; 

    memcpy((char *) &serverAddress.sin_addr.s_addr, 

     hostInfo->h_addr_list[0], hostInfo->h_length); 

    serverAddress.sin_port = htons(serverPort); 



    if (connect(socketDescriptor, 

       (struct sockaddr *) &serverAddress, 

       sizeof(serverAddress)) < 0) { 

    cerr << "cannot connect\n"; 

    exit(1); 

    } 



    cout << "\nWelcome to Car Customization Server. What are your orders?\n"; 

    cout << ">> Type of vehicle: Sedan, MPV, SUV, Luxury\n"; 

    cout << ">> Type of Styling: Sporty, Offroad\n"; 

    cout << ">> Eg. To order type: MPV Sporty\n"; 



    // Prompt the user for input, then read in the input, up to MAX_LINE 

    // charactars, and then dispose of the rest of the line, including 

    // the newline character. 

    cout << "Enter Order: "; 

    cin.get(buf, MAX_LINE, '\n'); 

    while (cin.get(c) && c != '\n') 

    ; //Loop does nothing except consume the spare bytes 





    // Stop when the user inputs a line with just a dot. 

    while (strcmp(buf, ".")) { //strcmp returns 0 when the two strings 

       //are the same, so this continues when 

       //they are different 

    // Send the line to the server. 

    if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) { 

     cerr << "cannot send data "; 

     close(socketDescriptor); //Note this is just like using files... 

     exit(1); 

    } 



    // Zero out the buffer. 

    memset(buf, 0x0, LINE_ARRAY_SIZE); 



    // Read the modified line back from the server. 

    if (recv(socketDescriptor, buf, MAX_LINE, 0) < 0) { 

     cerr << "didn't get response from server?"; 

     close(socketDescriptor); 

     exit(1); 

    } 



    cout << "results: " << buf << "\n"; 



    // Prompt the user for input, then read in the input, up to MAX_LINE 

    // charactars, and then dispose of the rest of the line, including 

    // the newline character. As above. 

    cout << "Enter Order: "; 

    cin.get(buf, MAX_LINE, '\n'); 

    while (cin.get(c) && c != '\n') 

     ; //again, consuming spare bytes 

    } 



    close(socketDescriptor); 

    return 0; 

} 

代码,以便在那里,如果有谁知道如何发回了字符串和成本。请回复。谢谢。

+1

由于使用C++构造,它无法编译为C。你为什么要标记它?另外:你的问题到底是什么? “如何做X?”似乎太宽泛。 –

+4

尽管使用单个空行将代码分段为段落很好,但您在另一个方向上走了很远。你展示的代码是否真正复制粘贴? –

+0

@AlgirdasPreidžius这是两者的结合。 –

回答

0

你可以收拾你的std :: string SLINE成通过复制字节的发送缓冲区:

memcpy(line, sline.c_str(), strlen(sline.c_str())) 

发送,然后在客户端解压的方式相同。

编辑: 请尝试下面的代码为您的服务器,这是你想要什么?

#include <arpa/inet.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <unistd.h> 
#include <iostream> 
#include <cstring> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string> 
#include <sstream> 

#define MAX_MSG 100 
#define LINE_ARRAY_SIZE (MAX_MSG+1) 

using namespace std; 

int main() 
{ 
    int listenSocket, connectSocket, i; 
    unsigned short int listenPort; 
    socklen_t clientAddressLength; 
    struct sockaddr_in clientAddress, serverAddress; 
    char line[LINE_ARRAY_SIZE]; 

    cout << "Enter port number to listen on (between 1500 and 65000): "; 
    cin >> listenPort; 

    listenSocket = socket(AF_INET, SOCK_STREAM, 0); 

    if (listenSocket < 0) { 
    cerr << "cannot create listen socket"; 
    exit(1); 
    } 

    serverAddress.sin_family = AF_INET; 
    serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); 
    serverAddress.sin_port = htons(listenPort); 

    if (bind(listenSocket, (struct sockaddr *) &serverAddress, 
      sizeof(serverAddress)) < 0) { 
    cerr << "cannot bind socket"; 
    exit(1); 
    } 

    listen(listenSocket, 5); 

    while (1) { 
    cout << "Waiting for TCP connection on port " << listenPort << " ...\n"; 
    clientAddressLength = sizeof(clientAddress); 
    connectSocket = accept(listenSocket, (struct sockaddr *) &clientAddress, 
          &clientAddressLength); 

    if (connectSocket < 0) { 
     cerr << "cannot accept connection "; 
     exit(1); 
    } 
    cout << " connected to " << inet_ntoa(clientAddress.sin_addr); 
    cout << ":" << ntohs(clientAddress.sin_port) << "\n"; 

    memset(line, 0x0, LINE_ARRAY_SIZE); 
    while (recv(connectSocket,line, MAX_MSG, 0) > 0) { 

    cout << " -- " << line << "\n"; 

    std::string delimiter[2]; 
    int i = 0; 
    double cost = 0; 
    std::string carType; 
    std::string carStyling; 
    std::string sline; 
    sline = line; 
    stringstream ssin(sline); 

    while (ssin.good() && i < 2){ 
     ssin >> delimiter[i]; 
     ++i; 
    } 
    sline = ""; 

    for(i = 0; i < 2; i++){ 
     cout << delimiter[i] << endl; 
    } 
    sline += "Your "; 
    carType = delimiter[0]; 

    if(carType.compare("Sedan")==0){ 
     sline += "Sedan"; 
     cost = 100000; 
    } 
    else if(carType.compare("MPV")==0){ 
     sline += "MPV"; 
     cost = 120000; 
    } 
    else if(carType.compare("SUV")==0){ 
     sline += "SUV"; 
     cost = 140000; 
    } 
    else if(carType.compare("Luxury")==0){ 
     sline += "Luxury"; 
     cost = 180000; 
    } 

    carStyling = delimiter[1]; 

    if(carStyling.compare("Sporty")==0){ 
     sline += " Sporty "; 
     cost = cost * 1.5; 
    } 

    else if(carStyling.compare("Offroad")==0){ 
     sline += " Offroad "; 
     cost = cost * 1.3; 
    } 

    sline += "will cost "; 
    std::ostringstream ss; 
    ss << cost; 
    sline += ss.str(); 

    sline.copy(line, sline.length()); 

    if (send(connectSocket, line, strlen(line) + 1, 0) < 0) 
     cerr << "Error: cannot send modified data"; 
     memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes 
    } 
    } 
} 
+2

为什么在'sline.length()'提供长度时使用'strlen'?这个额外的'memcpy'不需要,因为你可以直接在'send'的调用中使用'sline.c_str()'。 –

+0

你是对的,但是如果他想把“字符串和成本”作为一个发送。也许最好的办法是找出一些发送协议。例如,打包到传入字符串的缓冲区长度,然后字符串,然后四个字节int为成本。然后在另一边解开它。 –

+0

@PawełDymowski谢谢你。我现在就试试看。 –

相关问题