libuv-svace-build

Форк
0
/
test-udp-send-and-recv.c 
212 строк · 5.3 Кб
1
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
 *
3
 * Permission is hereby granted, free of charge, to any person obtaining a copy
4
 * of this software and associated documentation files (the "Software"), to
5
 * deal in the Software without restriction, including without limitation the
6
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
 * sell copies of the Software, and to permit persons to whom the Software is
8
 * furnished to do so, subject to the following conditions:
9
 *
10
 * The above copyright notice and this permission notice shall be included in
11
 * all copies or substantial portions of the Software.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
 * IN THE SOFTWARE.
20
 */
21

22
#include "uv.h"
23
#include "task.h"
24

25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28

29
#define CHECK_HANDLE(handle) \
30
  ASSERT_NE((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client, 0)
31

32
static uv_udp_t server;
33
static uv_udp_t client;
34

35
static int cl_send_cb_called;
36
static int cl_recv_cb_called;
37

38
static int sv_send_cb_called;
39
static int sv_recv_cb_called;
40

41
static int close_cb_called;
42

43

44
static void alloc_cb(uv_handle_t* handle,
45
                     size_t suggested_size,
46
                     uv_buf_t* buf) {
47
  static char slab[65536];
48
  CHECK_HANDLE(handle);
49
  ASSERT_LE(suggested_size, sizeof(slab));
50
  buf->base = slab;
51
  buf->len = sizeof(slab);
52
}
53

54

55
static void close_cb(uv_handle_t* handle) {
56
  CHECK_HANDLE(handle);
57
  ASSERT_EQ(1, uv_is_closing(handle));
58
  close_cb_called++;
59
}
60

61

62
static void cl_recv_cb(uv_udp_t* handle,
63
                       ssize_t nread,
64
                       const uv_buf_t* buf,
65
                       const struct sockaddr* addr,
66
                       unsigned flags) {
67
  CHECK_HANDLE(handle);
68
  ASSERT_OK(flags);
69

70
  if (nread < 0) {
71
    ASSERT(0 && "unexpected error");
72
  }
73

74
  if (nread == 0) {
75
    /* Returning unused buffer. Don't count towards cl_recv_cb_called */
76
    ASSERT_NULL(addr);
77
    return;
78
  }
79

80
  ASSERT_NOT_NULL(addr);
81
  ASSERT_EQ(4, nread);
82
  ASSERT(!memcmp("PONG", buf->base, nread));
83

84
  cl_recv_cb_called++;
85

86
  uv_close((uv_handle_t*) handle, close_cb);
87
}
88

89

90
static void cl_send_cb(uv_udp_send_t* req, int status) {
91
  int r;
92

93
  ASSERT_NOT_NULL(req);
94
  ASSERT_OK(status);
95
  CHECK_HANDLE(req->handle);
96

97
  r = uv_udp_recv_start(req->handle, alloc_cb, cl_recv_cb);
98
  ASSERT_OK(r);
99

100
  cl_send_cb_called++;
101
}
102

103

104
static void sv_send_cb(uv_udp_send_t* req, int status) {
105
  ASSERT_NOT_NULL(req);
106
  ASSERT_OK(status);
107
  CHECK_HANDLE(req->handle);
108

109
  uv_close((uv_handle_t*) req->handle, close_cb);
110
  free(req);
111

112
  sv_send_cb_called++;
113
}
114

115

116
static void sv_recv_cb(uv_udp_t* handle,
117
                       ssize_t nread,
118
                       const uv_buf_t* rcvbuf,
119
                       const struct sockaddr* addr,
120
                       unsigned flags) {
121
  uv_udp_send_t* req;
122
  uv_buf_t sndbuf;
123
  int r;
124

125
  if (nread < 0) {
126
    ASSERT(0 && "unexpected error");
127
  }
128

129
  if (nread == 0) {
130
    /* Returning unused buffer. Don't count towards sv_recv_cb_called */
131
    ASSERT_NULL(addr);
132
    return;
133
  }
134

135
  CHECK_HANDLE(handle);
136
  ASSERT_OK(flags);
137

138
  ASSERT_NOT_NULL(addr);
139
  ASSERT_EQ(4, nread);
140
  ASSERT(!memcmp("PING", rcvbuf->base, nread));
141

142
  /* FIXME? `uv_udp_recv_stop` does what it says: recv_cb is not called
143
    * anymore. That's problematic because the read buffer won't be returned
144
    * either... Not sure I like that but it's consistent with `uv_read_stop`.
145
    */
146
  r = uv_udp_recv_stop(handle);
147
  ASSERT_OK(r);
148

149
  req = malloc(sizeof *req);
150
  ASSERT_NOT_NULL(req);
151

152
  sndbuf = uv_buf_init("PONG", 4);
153
  r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb);
154
  ASSERT_OK(r);
155

156
  sv_recv_cb_called++;
157
}
158

159

160
TEST_IMPL(udp_send_and_recv) {
161
  struct sockaddr_in addr;
162
  uv_udp_send_t req;
163
  uv_buf_t buf;
164
  int r;
165

166
  ASSERT_OK(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
167

168
  r = uv_udp_init(uv_default_loop(), &server);
169
  ASSERT_OK(r);
170

171
  r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
172
  ASSERT_OK(r);
173

174
  r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb);
175
  ASSERT_OK(r);
176

177
  ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
178

179
  r = uv_udp_init(uv_default_loop(), &client);
180
  ASSERT_OK(r);
181

182
  /* client sends "PING", expects "PONG" */
183
  buf = uv_buf_init("PING", 4);
184

185
  r = uv_udp_send(&req,
186
                  &client,
187
                  &buf,
188
                  1,
189
                  (const struct sockaddr*) &addr,
190
                  cl_send_cb);
191
  ASSERT_OK(r);
192

193
  ASSERT_OK(close_cb_called);
194
  ASSERT_OK(cl_send_cb_called);
195
  ASSERT_OK(cl_recv_cb_called);
196
  ASSERT_OK(sv_send_cb_called);
197
  ASSERT_OK(sv_recv_cb_called);
198

199
  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
200

201
  ASSERT_EQ(1, cl_send_cb_called);
202
  ASSERT_EQ(1, cl_recv_cb_called);
203
  ASSERT_EQ(1, sv_send_cb_called);
204
  ASSERT_EQ(1, sv_recv_cb_called);
205
  ASSERT_EQ(2, close_cb_called);
206

207
  ASSERT_OK(client.send_queue_size);
208
  ASSERT_OK(server.send_queue_size);
209

210
  MAKE_VALGRIND_HAPPY(uv_default_loop());
211
  return 0;
212
}
213

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.