网络http自定制协议
Posted zhao111222333444
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络http自定制协议相关的知识,希望对你有一定的参考价值。
1 #include <cstdio>
2 #include <iostream>
3 #include <string>
4 #include <unistd.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <sys/socket.h>
8 #define CHECK_RET(q) if((q)==false)return -1;
9 #define LISTEN_BACKLOG 5
10
11 struct data_t
12 int num1;
13 int num2;
14 char op;
15 ;
16 class TcpSocket
17 private:
18 int _sockfd;
19 public:
20 TcpSocket():_sockfd(-1)
21 int GetFd()
22 return _sockfd;
23
24 void SetFd(int fd)
25 _sockfd = fd;
26
27 bool Socket()
28 _sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
29 if (_sockfd < 0)
30 perror("socket error");
31 return false;
32
33 return true;
34
35 bool Bind(const std::string &ip, const uint16_t port)
36 sockaddr_in addr;
37 addr.sin_family = AF_INET;
38 addr.sin_port = htons(port);
39 addr.sin_addr.s_addr = inet_addr(&ip[0]);
40 socklen_t len = sizeof(sockaddr_in);
41 int ret = bind(_sockfd, (sockaddr*)&addr, len);
42 if (ret < 0)
43 perror("bind error");
44 return false;
45
46 return true;
47
48 bool Listen(int backlog = LISTEN_BACKLOG)
49 //listen(描述符,同一时间连接数)
50 int ret = listen(_sockfd, backlog);
51 if (ret < 0)
52 perror("listen error");
53 return false;
54
55 return true;
56
57 bool Connect(const std::string &ip,const int port)
58 sockaddr_in addr;
59 addr.sin_family = AF_INET;
60 addr.sin_port = htons(port);
61 addr.sin_addr.s_addr = inet_addr(&ip[0]);
62 socklen_t len = sizeof(sockaddr_in);
63 //connect(描述符,服务端地址, 地址长度)
64 int ret = connect(_sockfd, (sockaddr*)&addr, len);
65 if (ret < 0)
66 perror("connect error");
67 return false;
68
69 return true;
70
71 bool Accept(TcpSocket *sock, std::string *ip = NULL,
72 uint16_t *port = NULL)
73 //int accept(监听套接字, 回去客户端地址, 长度)
74 sockaddr_in addr;
75 socklen_t len = sizeof(sockaddr_in);
76 int newfd = accept(_sockfd,(sockaddr*)&addr,&len);
77 if (newfd < 0)
78 perror("accept error");
79 return false;
80
81 sock->_sockfd = newfd;
82 if (ip != NULL)
83 *ip = inet_ntoa(addr.sin_addr);
84
85 if (port != NULL)
86 *port = ntohs(addr.sin_port);
87
88 return true;
89
90 bool Recv(std::string *buf)
91 //int recv(描述符,空间,数据长度,标志位)
92 //返回值:实际获取大小, 0-连接断开; -1-出错了
93 char tmp[4096] = 0;
94 int ret = recv(_sockfd, tmp, 4096, 0);
95 if (ret < 0)
96 perror("recv error");
97 return false;
98 else if (ret == 0)
99 printf("peer shutdown");
100 return false;
101
102 buf->assign(tmp, ret);
103 return true;
104
105 bool Send(const std::string &data)
106 //int send(描述符,数据,长度,标志位)
107 int total = 0;
W>108 while(total < data.size())
109 int ret = send(_sockfd, &data[0] + total,
110 data.size() - total, 0);
111 if (ret < 0)
112 perror("send error");
113 return false;
114
115 total += ret;
116
117 return true;
118
119 bool Close()
120 if (_sockfd != -1)
121 close(_sockfd);
122
123 return true;
124
125 ;
客户端:
1 #include "tcpsocket.hpp"
2
3 int main(int argc, char *argv[])
4
5 //通过参数传入要连接的服务端的地址信息
6 if (argc != 3)
7 printf("usage: ./tcp_cli srvip srvport\\n");
8 return -1;
9
10 std::string srvip = argv[1];
11 uint16_t srvport = std::stoi(argv[2]);
12
13 TcpSocket cli_sock;
14 //1. 创建套接字
15 CHECK_RET(cli_sock.Socket());
16 //2. 绑定地址信息(不推荐)
17 //3. 向服务端发起连接
18 CHECK_RET(cli_sock.Connect(srvip, srvport));
19 //4. 收发数据
20 struct data_t tmp;
21 tmp.num1 = 11;
22 tmp.num2 = 22;
23 tmp.op = '+';
24 int fd = cli_sock.GetFd();
25 send(fd, (void*)&tmp, sizeof(struct data_t), 0);
26 //tcp通信由于面向连接就不需要指定发送的地址,
27 //send接口的fd是客户端的fd,就是哪个套接字要发送数据
28 int result;
29 recv(fd, &result, sizeof(int), 0);
30 std::cout << result << std::endl;
31 //5. 关闭套接字
32 CHECK_RET(cli_sock.Close());
33 return 0;
34
服务端:
1 #include "tcpsocket.hpp"
2
3 int main(int argc, char *argv[])
4
5 //通过程序运行参数指定服务端要绑定的地址
6 // ./tcp_srv 192.168.2.2 9000
7 if (argc != 3)
8 printf("usage: ./tcp_src 192.168.2.2 9000\\n");
9 return -1;
10
11 std::string srvip = argv[1];
12 uint16_t srvport = std::stoi(argv[2]);
13 TcpSocket lst_sock;//监听套接字
14 //1. 创建套接字
15 CHECK_RET(lst_sock.Socket());
16 //2. 绑定地址信息
17 CHECK_RET(lst_sock.Bind(srvip, srvport));
18 //3. 开始监听
19 CHECK_RET(lst_sock.Listen());
20 while(1)
21 //4. 获取新建连接
22 TcpSocket clisock;
23 std::string cliip;
24 uint16_t cliport;
25 bool ret = lst_sock.Accept(&clisock, &cliip,&cliport);
26 if (ret == false)
27 continue;
28
29 std::cout<<"get newconn:"<< cliip<<"-"<<cliport<<"\\n";
30 //5. 收发数据--使用获取的新建套接字进行通信
31 int fd = clisock.GetFd();
32 struct data_t tmp;
33 recv(fd, &tmp, sizeof(struct data_t), 0);
34 //fd是指从哪个套接字获取内容
35 int result;
36 if (tmp.op == '+')
37 result = tmp.num1 + tmp.num2;
38 else
39 result = 100;
40
41 send(fd, &result, sizeof(int), 0);
42
43 //6. 关闭套接字
44 lst_sock.Close();
45
以上是关于网络http自定制协议的主要内容,如果未能解决你的问题,请参考以下文章
网络协议 17 - HTTPDNS:私人定制的 DNS 服务