wangzhengquan
2020-10-13 34ddc11240baa01d15b24f09e39d09cb4dd15c75
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "net_mod_socket.h"
#include "socket_io.h"
#include "net_mod_socket_io.h"
 
 
std::map<std::string, rio_t *> NetModSocket::connectionMap;
 
NetModSocket::NetModSocket() 
{
        
}
 
 
NetModSocket::~NetModSocket() {
  
}
 
int NetModSocket::sendandrecv(net_node_t *node_arr, int arrlen, void *send_buf, int send_size, 
  net_mod_recv_msg_t ** recv_arr, int *recv_arr_size) {
 
  int i, n, clientfd;
  char portstr[32];
  net_node_t *node;
  char mapKey[256];
  void *recv_buf;
  int recv_size;
  char response_head_bs[NET_MODE_RESPONSE_HEAD_LENGTH];
  net_mod_request_head_t request_head;
  net_mod_response_head_t response_head;
  std::map<std::string, rio_t*>::iterator mapIter;
  rio_t *rio;
  net_mod_recv_msg_t *ret_arr = (net_mod_recv_msg_t *)calloc(arrlen, sizeof(net_mod_recv_msg_t));
  
  for (i = 0; i< arrlen; i++) {
 
    node = &node_arr[i];
    if(node->host == NULL) {
      // 本地发送
      shmModSocket.sendandrecv(send_buf, send_size, node->key, &recv_buf, &recv_size);
      goto LABEL_ARR_PUSH;
    }
    sprintf(mapKey, "%s:%d", node->host, node->port);
    if( ( mapIter = connectionMap.find(mapKey)) != connectionMap.end()) {
      rio = mapIter->second;
    } else {
      rio = (rio_t *)malloc(sizeof(rio_t));
      sprintf(portstr, "%d", node->port);
      clientfd = Open_clientfd(node-> host, portstr);
      Rio_readinitb(rio, clientfd);
      connectionMap.insert({mapKey, rio});
 
    }
 
    request_head.mod = REQ_REP;
    request_head.key = node->key;
    request_head.content_length = send_size;
    if(rio_writen(rio->rio_fd, NetModSocket::encode_request_head(request_head), NET_MODE_REQUEST_HEAD_LENGTH) != NET_MODE_REQUEST_HEAD_LENGTH) {
      err_exit(errno, "NetModSocket::send head rio_writen");
 
    }
 
    if(rio_writen(rio->rio_fd, send_buf, send_size) != send_size ) {
       err_exit(errno, "NetModSocket::send conent rio_writen");
    }
 
 
    if ( rio_readnb(rio, response_head_bs, NET_MODE_RESPONSE_HEAD_LENGTH) !=  NET_MODE_RESPONSE_HEAD_LENGTH) {
      err_exit(errno, "NetModSocket::send  rio_readnb");
    }
 
    response_head =  NetModSocket::decode_response_head(response_head_bs);
 
    recv_buf = malloc(response_head.content_length);
    if(recv_buf == NULL) {
      err_exit(errno, "NetModSocket::send malloc");
    }
    if ( (recv_size = rio_readnb(rio, recv_buf, response_head.content_length) ) !=  response_head.content_length) {
      err_exit(errno, "NetModSocket::send  rio_readnb");
    }
 
LABEL_ARR_PUSH:
    strcpy( ret_arr[i].host, node->host);
    ret_arr[i].port = node->port;
    ret_arr[i].key = node->key;
    ret_arr[i].content = recv_buf;
    ret_arr[i].content_length = recv_size;
  }
  *recv_arr = ret_arr;
  *recv_arr_size = i;
 
  return i;
     
}
 
 
void NetModSocket::free_recv_msg_arr(net_mod_recv_msg_t * arr, size_t size) {
 
  for(int i =0; i< size; i++) {
    free(arr[i].content);
  }
 
}
 
// ssize_t recv(void *buf, size_t len) {
 
//     return rio_readlineb(&rio, buf, MAXLINE);
  
// }
 
void * NetModSocket::encode_request_head(net_mod_request_head_t & request) {
  char * head = (char *)malloc(NET_MODE_REQUEST_HEAD_LENGTH);
  PUT(head, htonl(request.mod));
  PUT(head + 4, htonl(request.key));
  PUT(head + 8, htonl(request.content_length));
  return head;
}
 
net_mod_request_head_t  NetModSocket::decode_request_head(void *_headbs) {
  char *headbs = (char *)_headbs;
  net_mod_request_head_t head;
  head.mod = ntohl(GET(headbs));
  head.key = ntohl(GET(headbs + 4));
  head.content_length = ntohl(GET(headbs + 8));
  return head;
}
 
void * NetModSocket::encode_response_head(net_mod_response_head_t & response) {
  char * head = (char *)malloc(NET_MODE_RESPONSE_HEAD_LENGTH);
  PUT(head, htonl(response.content_length));
  return head;
}
 
net_mod_response_head_t  NetModSocket::decode_response_head(void *_headbs) {
  char *headbs = (char *)_headbs;
  net_mod_response_head_t head;
  head.content_length = ntohl(GET(headbs));
  return head;
}