Linux 下Socket 通信

进程之间用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() {
  /*connect()向服务器发送连接请求*/
  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”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值