编辑TCP客户端/服务器创建反向波兰符号计算器服务器

editing tcp client/server to create reverse polish notation calculator server

本文关键字:服务器 符号 计算器 创建 TCP 客户端 编辑      更新时间:2023-10-16

我正在尝试创建一个反向波兰符号计算器服务器,我得到了客户端和服务器的源代码"见下文",并要求修改它以创建服务器。我有一个关于如何去创建计算器的想法,但我在哪里插入我的计算器代码在这个现有的服务器源代码。或者它进入现有的客户端源代码。

客户端源代码:

#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 socketn";
    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 connectn";
    exit(1);
  }
  cout << "nEnter some lines, and the server will modify them andn";
  cout << "send them back.  When you are done, enter a line withn";
  cout << "just a dot, and nothing else.n";
  cout << "If a line is more than " << MAX_LINE << " characters, thenn";
  cout << "only the first " << MAX_LINE << " characters will be used.nn";
  // 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 << "Input: ";
  cin.get(buf, MAX_LINE, 'n');
  while (cin.get(c) && c != 'n')
    ;
  // Stop when the user inputs a line with just a dot.
  while (strcmp(buf, ".")) {
    // Send the line to the server.
    if (send(socketDescriptor, buf, strlen(buf) + 1, 0) < 0) {
      cerr << "cannot send data ";
      close(socketDescriptor);
      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 << "Modified: " << 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 << "Input: ";
    cin.get(buf, MAX_LINE, 'n');
    while (cin.get(c) && c != 'n')
      ;
  }
  close(socketDescriptor);
  return 0;
}

服务器源代码:

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

#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] != ''; i++)
        line[i] = toupper(line[i]);
      // 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
    }
  }
}
while (recv(connectSocket, line, MAX_MSG, 0) > 0) {
      //process line, so retrieve numbers, operation
      //and call calculator(numbers, operation) and 
      //convert result to string result
      // Send result back to client.
      if (send(connectSocket, result, strlen(line) + 1, 0) < 0)
        cerr << "Error: cannot send modified data";