序列化和反序列化(Linux)
1 序列化和反序列化
write和read实质是拷贝函数
1.1序列化和反序列化的概述:



2网络版计算器
2.1代码实现

先把日志拷贝过来
2.1.1必须先要有网络功能
先把 TcpServer.hpp编写号
#pragma once #include <cstdint> #include "Socket.hpp" #include "./logs/ljwlog.h" class TcpServer { public: TcpServer() {} bool InitServer() {} void Start() {} ~TcpServer() {} private: uint16_t port; }; 
2.1.2 把套接字接口封装一下方便使用
#pragma once #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <pthread.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/wait.h> #include <netinet/in.h> using namespace std; class Sock { public: Sock() {} ~Sock() {} public: void Socket()//创建套接字的接口 {} void bind()//绑定的接口 {} void Listen()//监听状态的接口 {} int Accept()//获取连接的接口 {} int Connect()//方便两个客户端和服务器都能使用这个Sock的这个公共方法 {} private: int sockfd_; };
2.1.3 TcpServer.hpp接口的补充

#pragma once #include <cstdint> #include "Socket.hpp" #include "./logs/ljwlog.h" class TcpServer { public: TcpServer() {} bool InitServer() { //先创建套接字,再绑定,设置监听状态 listensock_.Socket(); listensock_.bind(); listensock_.Listen(); } void Start() { while(true) { int sockfd = listensock_.Accept(); } } ~TcpServer() {} private: uint16_t port_; Sock listensock_; //叫listen套接字,Listen完后有真正的网络文件描述符 }; 2.1.4 Sock.hpp接口的补充
#pragma once #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <pthread.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/wait.h> #include <netinet/in.h> #include <cstring> #include "./logs/ljwlog.h" using namespace std; enum{ SocketErr = 2, BindErr, ListenErr }; const int backlog = 10; class Sock { public: Sock() {} ~Sock() {} public: void Socket()//创建套接字的接口 { sockfd_ = socket(AF_INET, SOCK_STREAM, 0);//流式套接字 第二个参数是协议类型 if(sockfd_ < 0) { FATAL("Socket errno,error:%d,errstring:%s", errno, strerror(errno)); exit(SocketErr); } } void Bind(uint16_t port)//绑定的接口 { struct sockaddr_in local; memset(&local, 0, sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons(port);//主机转网络 local.sin_addr.s_addr = INADDR_ANY;//ip默认0.0.0.0 if(bind(sockfd_, (struct sockaddr*)&local, sizeof(local)) < 0) { FATAL("Bind errno,error:%d,errstring:%s", errno, strerror(errno)); exit(BindErr); } } void Listen()//监听状态的接口 { if(listen(sockfd_, backlog) < 0) { FATAL("Listen errno,error:%d,errstring:%s", errno, strerror(errno)); exit(ListenErr); } } // 知道谁链接的我 int Accept(string *clientip, uint16_t *clientport)//获取连接的接口 { struct sockaddr_in peer;//远端的意思 socklen_t len = sizeof(peer); int newfd = accept(sockfd_, (struct sockaddr*)&peer, &len); if(newfd < 0) { WARN("accept error, %s: %d", strerror(errno), errno); return -1; } //网络转主机 //拿出客户端的ip和端口号 char ipstr[64]; inet_ntop(AF_INET, &peer.sin_addr, ipstr, sizeof(ipstr));//网络转主机 *clientip = ipstr;//网络转主机 *clientport = ntohs(peer.sin_port);//网络转主机 return newfd; } void Close() { close(sockfd_); } int Connect()//方便两个客户端和服务器都能使用这个Sock的这个公共方法 { return 0; } private: int sockfd_; };2.1.4 TcpServer.hpp提供服务

2.1.5定制协议(Protocol)(约定好)
双方约定好,把请求放在Request(请求),结果放在Response(响应)
约定好了,最好就不要动他了

#pragma once #include<iostream> class Request { public: public: int x; int y; char op;// + - * / % }; class Response { public: public: int result; int code;// 0,可信,否则!0具体是几,表明对应的错误原因 };2.1.6 (手写)序列化和反序列化
serialization 序列化(把struct 转换成 字符串)
deserialization 反序列化


2.1.6.1序列化


2.1.6.2反序列化



2.1.6.3添加报头(要往网络里发 先添加报头)

这种

