如何在C中将字符串从服务器返回到客户端?

时间:2017-10-06 06:12:53

标签: c++ c port stringstream

我需要将一个字符串发送回客户端,其中包括车辆成本和带修改器的车辆(carStyling)。我想将包含sline和cost的字符串返回给客户端。喜欢的东西;

  

你的轿车越野将花费15万美元。

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

#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 个答案:

答案 0 :(得分:0)

您可以通过复制字节将std :: string sline打包到发送缓冲区中:

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.model.testsuite.*;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner
import java.util.Random 
import com.eviware.soapui.model.testsuite.TestRunner.Status



// Define your testCase pointer
//def testcase = testRunner.testCase.testSuite.project.testSuites["TestSuite - User Management REST API"].getTestCaseByName ("Authenticate User")

def counterUser = testRunner.testCase.testSuite.getPropertyValue( "counter" )

int value = counterUser.toInteger()
String tester = ""
30.times {
 value = value + 1
 tester = "tester " + value.toString()
 testRunner.testCase.testSuite.setPropertyValue( "userName", tester )

 testRunner.runTestStepByName("POST - createUser - Create a User")
}
testRunner.testCase.testSuite.setPropertyValue( "counter", value.toString() )

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

编辑: 请为您的服务器尝试以下代码,这是您想要的吗?

int value = counterUser.toInteger()