2017-10-06 35 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; 

} 

코드입니다. 회신 해주십시오. 고맙습니다.

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

가 보내 다음 클라이언트 측에서 그것을 같은 방식으로 압축을 풉니 다 :

+1

C++ 구문을 사용하기 때문에 C로 컴파일되지 않습니다. 왜 그걸 붙인거야? 또한 귀하의 질문은 무엇입니까? "X를하는 방법?" 너무 넓은 것 같습니다. –

+4

하나의 빈 줄이있는 단락으로 코드를 분리하는 것이 가독성이 좋지만 다른 방향으로 조금 멀리 갔을 수도 있습니다. 표시하는 코드는 실제로 실제로 복사하여 붙여 넣을 수 있습니까? –

+0

@ AlgirdasPreidžius 둘 다 결합 된 것입니다. –

답변

0

당신은 복사 바이트 버퍼를 보내기로 표준 : : 문자열 sline 팩 수 있습니다.

편집 : 아래의 코드를 사용해 보시기 바랍니다. 원하는 내용입니까?

#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를 4 바이트로 지정합니다. 그런 다음 다른쪽에 포장을 풉니 다. –

+0

@ PawełDymowski 감사합니다. 나는 그것을 지금 시험해 볼 것이다. –