admin管理员组文章数量:1319483
I'm making a simple socket proxy with GCD APIs, after my proxy server accepts() the client and connects() to the requested host, I'm forwarding data between them like this:
static void proxy_forward_fd(dispatch_queue_t queue, int fd_client, int fd_proxy) {
dispatch_io_t io_client = dispatch_io_create(DISPATCH_IO_STREAM, fd_client, queue, ^(int error) {
if (error) {
printf("Error creating client IO for FD %d: %s (%d)\n", fd_client, strerror(error), error);
}
printf("Closing client FD %d\n", fd_client);
close(fd_client);
});
dispatch_io_t io_proxy = dispatch_io_create(DISPATCH_IO_STREAM, fd_proxy, queue, ^(int error) {
if (error) {
printf("Error creating proxy IO for FD %d: %s (%d)\n", fd_proxy, strerror(error), error);
}
printf("Closing proxy FD %d\n", fd_proxy);
close(fd_proxy);
});
dispatch_io_set_low_water(io_client, 1);
dispatch_io_set_low_water(io_proxy, 1);
dispatch_io_read(io_client, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t data, int error) {
if (error) {
printf("Error reading client IO for FD %d: %s (%d)\n", fd_client, strerror(error), error);
}
printf("Client (done=%d, data=%zu, error=%d)\n", done, data ? dispatch_data_get_size(data) : 0, error);
// Client is sending data to proxy
if (data) {
dispatch_io_write(io_proxy, 0, data, queue, ^(bool done, dispatch_data_t data, int error) {});
}
// Client EOF, close both
if (done) {
dispatch_io_close(io_client, 0);
dispatch_io_close(io_proxy, 0);
}
});
dispatch_io_read(io_proxy, 0, SIZE_MAX, queue, ^(bool done, dispatch_data_t data, int error) {
if (error) {
printf("Error reading proxy IO for FD %d: %s (%d)\n", fd_proxy, strerror(error), error);
}
printf("Proxy (done=%d, data=%zu, error=%d)\n", done, data ? dispatch_data_get_size(data) : 0, error);
// Proxy is sending data to client
if (data) {
dispatch_io_write(io_client, 0, data, queue, ^(bool done, dispatch_data_t data, int error) {});
}
// Proxy EOF, close both
if (done) {
dispatch_io_close(io_client, 0);
dispatch_io_close(io_proxy, 0);
}
});
}
I'm testing this by sending a request to an HTTP server (python3 -mhttp.server --bind 127.0.0.1
), the data is received but the client's end is never closed until the client itself disconnects:
Accepted client (fd=4)
Connected to proxy (fd=5)
Proxying (client_fd=4, proxy_fd=5)
Client (fd=4, done=0, data=18, error=0) # Sends "GET / HTTP/1.1\r\n\r\n"
Proxy (fd=5, done=0, data=936, error=0) # Sends "HTTP/1.1 200 OK..."
Proxy (fd=5, done=1, data=0, error=0) # Closes connection
Closing proxy (fd=5) # dispatch_io_close(io_proxy)
# Closing client never happens until client disconnects
If I add DISPATCH_IO_STOP
flag to both of my dispatch_io_close
calls, then it closes but data is not received by the client (it closes before write is finished).
Why is that and what is the correct way to implement a socket proxy with GCD?
本文标签: macosGCD dispatchioclose not closing IOStack Overflow
版权声明:本文标题:macos - GCD dispatch_io_close not closing IO - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742058963a2418467.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论