-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtcp_socket.cpp
More file actions
107 lines (97 loc) · 3.04 KB
/
tcp_socket.cpp
File metadata and controls
107 lines (97 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include"tcp_socket.h"
#include"comm_socket.h"
TcpSocket::TcpSocket(){
recv_pos_ = recv_buffer_;
}
TcpSocket::~TcpSocket(){
Close();
}
bool TcpSocket::Create(){
socket_fd_ = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd_ < 0){
perror("build tcp socket failed!\n");
return false;
}
return true;
}
bool TcpSocket::Create(int sock_fd){
socket_fd_ = sock_fd;
if (socket_fd_ < 0){
perror("build tcp socket failed!\n");
return false;
}
return true;
}
bool TcpSocket::Accept(int* socket_fd, struct sockaddr_in* client_addr){
int socket_len = sizeof(struct sockaddr_in);
int ret = accept(socket_fd_, (sockaddr*)client_addr, (socklen_t*)&socket_len);
if (ret < 0){
perror("tcp accept failed!\n");
return false;
}
*socket_fd = ret;
return true;
}
bool TcpSocket::GetPeerAddr(){
socklen_t len = sizeof(peer_addr_);
if (getpeername(socket_fd_, (sockaddr*)&peer_addr_, &len) < 0){
perror("tcp socket get peer addr failed!\n");
return false;
}
return true;
}
bool TcpSocket::Listen(int max_num){
int ret = listen(socket_fd_, max_num);
if (ret < 0){
perror("tcp listen failed!");
return false;
}
return true;
}
int TcpSocket::SendPacket(char* data, int len){
//send 4 bytes head to indicates the following packet's size
uint32_t netorder_len = htonl(len);
Send((char*)&netorder_len, 4);
Send(data, len);
return len;
}
int TcpSocket::RecvPacket(char* out_recv_buffer, int* recved_len){
int recv_bytes = Recv(recv_pos_, (uint64_t)(TCP_BUF_SIZE) + recv_buffer_ - recv_pos_);
if (recv_bytes == 0){//peer side close the connection
perror("peer disconnect\n");
return -1;
}
if (recv_bytes < 0){ //error happens
perror("tcp receive failed\n");
return -1;
}
//received data
recv_pos_ += recv_bytes;
int complete_packet_num = 0, complete_packet_bytes = 0, cur_packet_len = 0;
char* read_pos = recv_buffer_;
const int kHeadLen = 4;
while(true){
if (recv_pos_ - read_pos < kHeadLen){
break;
}
cur_packet_len = ntohl(*(uint32_t*)read_pos); //get data length of another packet
if(read_pos + kHeadLen + cur_packet_len > recv_pos_ ){//not another complete pack
break;
}
//change the packet_len from net order to host order for caller use
*(uint32_t*)read_pos = cur_packet_len;
read_pos += kHeadLen + cur_packet_len;
complete_packet_bytes += (kHeadLen + cur_packet_len);//another complete packet
complete_packet_num ++;
}
if (complete_packet_bytes){
//copy data to out buffer
memcpy(out_recv_buffer, recv_buffer_, complete_packet_bytes);
*recved_len = complete_packet_bytes;
//update the recv_buffer_
int left_size = recv_pos_ - recv_buffer_ - complete_packet_bytes;
memcpy(recv_buffer_, read_pos, left_size);
recv_pos_ = recv_buffer_ + left_size;
}
return complete_packet_num;
}