进程之间用socket进行通信:
利用socket编写Server端与Client端进行通信,由于建立套接字的部分的代码十分类似,而且代码并不是很简练,所以我对其进行封装,可以直接调用。
利用Makefile进行编译,链接
Makefile
src = $(wildcard ./*.cpp)
obj = $(patsubst %.cpp, %.o, $(src))
target = app
CC = g++
$(target): $(obj)
$(CC) $(obj) -o $(target)
%.o: %.cpp
$(CC) -c $< -o $@
.PHONY: clean
clean:
rm -rf $(obj) $(target)
Server
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <memory>
#define maxBuf (1 << 20)
#ifndef _SERVER_H_
#define _SERVER_H_
static char messages[maxBuf];
class ServerSock {
public:
ServerSock(char *ip, char *port);
~ServerSock();
void serverBind();
void error(char *error);
void serverListen();
void serverAccept();
void setMessages(char *others);
virtual void serverWrite();
private:
char *_port;
char *_ip;
int serverFd;
int clientFd;
struct sockaddr_in serverAddr;
struct sockaddr_in clientAddr;
socklen_t clientAddrLen;
};
#endif
#include "server.h"
void ServerSock::error(char *error) {
std::cout << error << std::endl;
exit(1);
}
ServerSock::ServerSock(char *ip, char *port) {
this->_ip = ip;
this->_port = port;
this->clientAddrLen = sizeof(clientAddr);
this->serverFd = socket(PF_INET, SOCK_STREAM, 0);
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip);
serverAddr.sin_port = htons(atoi(port));
}
void ServerSock::serverBind() {
if (bind(serverFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) ==
-1) {
this->error(const_cast<char *>("bind() error!"));
}
}
void ServerSock::serverListen() {
if (listen(serverFd, 5) == -1) {
this->error(const_cast<char *>("listen() error!"));
}
}
void ServerSock::serverAccept() {
clientFd = accept(serverFd, (struct sockaddr *)&clientAddr, &clientAddrLen);
if (clientFd == -1) {
this->error(const_cast<char *>("accept() error!"));
}
}
void ServerSock::serverWrite() {
int nowLen = 0;
int allLen = sizeof(messages);
int getLen = 0;
while (getLen < allLen) {
nowLen = write(clientFd, messages + getLen, allLen - getLen);
getLen += nowLen;
}
}
void ServerSock::setMessages(char *others) { strcpy(messages, others); }
ServerSock::~ServerSock() {
close(clientFd);
close(serverFd);
}
#include "server.h"
int main(int argc, char *argv[]) {
char others[] = "I am server";
ServerSock *server= new ServerSock(argv[1], argv[2]);
server->serverBind();
server->serverListen();
server->serverAccept();
server->setMessages(others);
server->serverWrite();
delete server;
return 0;
}
Client
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <memory>
#define maxBuf (1 << 20)
#ifndef _CLIENT_H_
#define _CLIENT_H_
static char reciveBuf[maxBuf];
class ClientSock {
public:
ClientSock(char *ip, char *port);
~ClientSock() { close(clientFd); };
void error(char *error);
void clientConnect();
virtual void clientRead();
private:
char *_port;
char *_ip;
int clientFd;
struct sockaddr_in serverAddr;
};
#endif
#include "client.h"
void ClientSock::error(char *error) {
std::cout << error << std::endl;
exit(1);
}
ClientSock::ClientSock(char *ip, char *port) {
this->_ip = ip;
this->_port = port;
this->clientFd = socket(PF_INET, SOCK_STREAM, 0);
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip);
serverAddr.sin_port = htons(atoi(port));
}
void ClientSock::clientConnect() {
if (connect(clientFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) ==
-1) {
this->error(const_cast<char *>("connect() error!"));
}
}
void ClientSock::clientRead() {
char buf[maxBuf];
int strLen = 0;
int allLen=sizeof(buf);
strLen = read(clientFd, buf, allLen);
if (strLen == -1) {
this->error(const_cast<char *>("read() error!"));
}
std::cout << "I accept from server information: " << buf << std::endl;
}
#include "client.h"
int main(int argc, char *argv[]) {
char buf[30];
ClientSock *client = new ClientSock(argv[1], argv[2]);
client->clientConnect();
client->clientRead();
delete client;
return 0;
}
Shell文件进行自动化编译和清除.obj和可执行文件
cd Server
make
./app 127.0.0.1 9190
cd Client
make
./app 127.0.0.1 9190
make clean
cd ..
cd Server
make clean
结果: Client端收到Server端的消息 “I am server”
|