#ifndef __SERVER_HPP__
#define __SERVER_HPP__
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include "Protocol.hpp"
using namespace std;
class server{
private:
int port;
int lsock;
public:
server(int _p):port(_p),lsock(-1)
{}
void initServer()
{
lsock = socket(AF_INET, SOCK_STREAM, 0);
if( lsock < 0 )
{
cerr << "socket error " << endl;
exit(2);
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(port);
local.sin_addr.s_addr = INADDR_ANY;
if(bind(lsock, (struct sockaddr*)&local, sizeof(local)) < 0){
cerr << "bind error!" << endl;
exit(3);
}
if(listen(lsock, 5) < 0){
cerr << "listen error!\n" << endl;
}
}
void cal(int sock)
{
request_t rq;
response_t rsp={4, 0};
ssize_t s = recv(sock, &rq, sizeof(rq), 0);
if(s > 0){
rsp.code = 0;
switch(rq.op){
case '+':
rsp.result = rq.x + rq.y;
break;
case '-':
rsp.result = rq.x - rq.y;
break;
case '*':
rsp.result = rq.x * rq.y;
break;
case '/':
if(rq.y != 0){
rsp.result = rq.x / rq.y;
}
else{
rsp.code = 1;
}
break;
case '%':
if(rq.y != 0){
rsp.result = rq.x + rq.y;
}
else{
rsp.code = 2;
}
break;
default:
rsp.code = 3;
break;
}
}
send(sock, &rsp, sizeof(rsp), 0);
close(sock);
}
void start()
{
struct sockaddr_in peer;
for(;;){
socklen_t len = sizeof(peer);
int sock = accept(lsock, (struct sockaddr*)&peer,&len);
if( sock < 0 ){
cerr << "accept error!" << endl;
continue;
}
if(fork() == 0){
if(fork() > 0){
exit(0);
}
close(lsock);
cal(sock);
exit(0);
}
close(sock);
waitpid(-1, nullptr, 0);
}
}
~server()
{
close(lsock);
}
};
#endif
#include "Server.hpp"
void Menu(string proc)
{
cout << "usage: \n\t";
cout << proc << " port" << endl;
}
int main(int argc, char *argv[])
{
if(argc != 2){
Menu(argv[0]);
exit(1);
}
server *sp = new server(atoi(argv[1]));
sp->initServer();
sp->start();
return 0;
}
#ifndef __CLIENT_HPP__
#define __CLIENT_HPP__
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include "Protocol.hpp"
using namespace std;
class client{
private:
int port;
string ip;
int sock;
public:
client(string _ip, int _p)
:ip(_ip), port(_p),sock(-1)
{}
void initClient()
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if( sock < 0 )
{
cerr << "socket error " << endl;
exit(2);
}
}
void cal(int sock)
{
request_t rq;
response_t rsp={4, 0};
ssize_t s = recv(sock, &rq, sizeof(rq), 0);
if(s > 0){
rsp.code = 0;
switch(rq.op){
case '+':
rsp.result = rq.x + rq.y;
break;
case '-':
rsp.result = rq.x - rq.y;
break;
case '*':
rsp.result = rq.x * rq.y;
break;
case '/':
if(rq.y != 0){
rsp.result = rq.x / rq.y;
}
else{
rsp.code = 1;
}
break;
case '%':
if(rq.y != 0){
rsp.result = rq.x + rq.y;
}
else{
rsp.code = 2;
}
break;
default:
rsp.code = 3;
break;
}
}
send(sock, &rsp, sizeof(rsp), 0);
close(sock);
}
void start()
{
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip.c_str());
if(connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0){
cerr << "connect error!" << endl;
exit(2);
}
response_t rsp;
request_t rq;
cout << "data1# ";
cin >> rq.x;
cout << "data2# ";
cin >> rq.y;
cout << "op# ";
cin >> rq.op;
send(sock, &rq, sizeof(rq), 0);
recv(sock, &rsp, sizeof(rsp), 0);
cout << "code : " << rsp.code << endl;
cout << "result: " << rsp.result << endl;
}
~client()
{
close(sock);
}
};
#endif
#include "Client.hpp"
void Menu(string proc)
{
cout << "usage: \n\t";
cout << proc << " svr_ip svr_port" << endl;
}
int main(int argc, char *argv[])
{
if(argc != 3){
Menu(argv[0]);
exit(1);
}
client *cp = new client(argv[1], atoi(argv[2]));
cp->initClient();
cp->start();
return 0;
}
#ifndef __PROTOCOL_HPP__
#define __PROTOCOL_HPP__
#include <iostream>
typedef struct request{
int x;
int y;
char op;
}request_t;
typedef struct response{
int code;
int result;
}response_t;
#endif
FLAG=-std=c++11 -lpthread
.PHONY:all
all:Client Server
Client:Client.cc
g++ -o $@ $^ $(FLAG) -static
Server:Server.cc
g++ -o $@ $^ $(FLAG) -g
.PHONY:clean
clean:
rm -f Client Server
运行效果
