编辑TCP客户端/服务器创建反向波兰符号计算器服务器
editing tcp client/server to create reverse polish notation calculator server
我正在尝试创建一个反向波兰符号计算器服务器,我得到了客户端和服务器的源代码"见下文",并要求修改它以创建服务器。我有一个关于如何去创建计算器的想法,但我在哪里插入我的计算器代码在这个现有的服务器源代码。或者它进入现有的客户端源代码。
客户端源代码:
#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";
相关文章:
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- "unknown ca"自生成的 CA、证书和客户端/服务器
- vscode g++链路故障:体系结构x86_64的未定义符号
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- 使用gcc从静态链接的文件中查找可选符号
- C++中无符号字符溢出
- 使用无符号字符数组有效存储内存
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 未解析的外部符号 CORBA 服务器
- 在 CORBA 客户端/服务器应用程序中将无符号的长整型(从 C++)断言为长整型 (Java)
- 有什么方法可以在内部镜像Microsoft的符号服务器吗?
- 编辑TCP客户端/服务器创建反向波兰符号计算器服务器
- C++ wxsocket TCP 服务器发送无符号字符数组,但 python 客户端再获得 4 个字节