gpt4 book ai didi

c++ - 如何用C语言将字符串从服务器返回到客户端?

转载 作者:行者123 更新时间:2023-11-30 21:06:54 24 4
gpt4 key购买 nike

我需要将一个字符串发送回客户端,其中包括车辆的成本和带有修饰符(carStyling)的车辆。我想向客户端返回一个包含直线和成本的字符串。类似的东西;

Your Sedan Offroad will cost $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;

}

所以,如果有人知道如何发回字符串和成本。请回复。谢谢。

最佳答案

您可以通过复制字节将 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
}
}
}

关于c++ - 如何用C语言将字符串从服务器返回到客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46599358/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com