#include #if defined(_WIN32) || defined(_WIN64) #include #else #include #include #endif /* ================================================================================================================== */ /* [套接字输入流子类]: c_SocketInStream 内部具体化上下文 */ typedef struct { c_InStream_t base; c_socket_t sock; c_Allocator_t allocator; } c_SocketInImpl_t; static c_err_t _SocketIn_Read(c_InStream_t* self, void* buf, c_size_t len, c_size_t* bytes_read) { c_SocketInImpl_t* impl = (c_SocketInImpl_t*)self; if (impl->sock == C_INVALID_SOCKET || !buf || len == 0) return C_ERR_PARAM; /* 执行底层网络字节流套接字拦截 */ #if defined(_WIN32) || defined(_WIN64) int n = recv(impl->sock, (char*)buf, (int)len, 0); #else ssize_t n = recv(impl->sock, buf, (size_t)len, 0); #endif if (n == 0) { if (bytes_read) *bytes_read = 0; return C_ERR_OUTOFBOUND; /* 对端优雅关闭连接 */ } if (n == C_SOCKET_ERROR) { if (bytes_read) *bytes_read = 0; return C_ERR_FAIL; /* 网络链路异常断开 */ } if (bytes_read) *bytes_read = (c_size_t)n; return ( (c_size_t)n == len ) ? C_SUCCESS : C_ERR_OK; /* 部分读取或完全读取皆视为合规 */ } static void _SocketIn_Destroy(c_InStream_t* self) { c_SocketInImpl_t* impl = (c_SocketInImpl_t*)self; c_Allocator_t alloc = impl->allocator; c_Allocator_Free(&alloc, impl); } static const c_InStreamVtbl_t g_SocketInVtbl = { _SocketIn_Read, _SocketIn_Destroy }; c_err_t c_SocketInStream_Create(c_InStream_t** out_stream, c_socket_t sock, c_Allocator_t* allocator) { if (!out_stream || sock == C_INVALID_SOCKET) return C_ERR_PARAM; c_Allocator_t alloc = allocator ? *allocator : c_DefaultAllocator; c_SocketInImpl_t* impl = (c_SocketInImpl_t*)c_Allocator_Calloc(&alloc, 1, sizeof(c_SocketInImpl_t)); if (!impl) return C_ERR_NOMEM; impl->base.vtbl = &g_SocketInVtbl; impl->sock = sock; impl->allocator = alloc; *out_stream = &impl->base; return C_SUCCESS; } /* ================================================================================================================== */ /* [套接字输出流子类]: c_SocketOutStream 内部具体化上下文 */ typedef struct { c_OutStream_t base; c_socket_t sock; c_Allocator_t allocator; } c_SocketOutImpl_t; static c_err_t _SocketOut_Write(c_OutStream_t* self, const void* buf, c_size_t len, c_size_t* bytes_written) { c_SocketOutImpl_t* impl = (c_SocketOutImpl_t*)self; if (impl->sock == C_INVALID_SOCKET || !buf || len == 0) return C_ERR_PARAM; #if defined(_WIN32) || defined(_WIN64) int n = send(impl->sock, (const char*)buf, (int)len, 0); #else /* MSG_NOSIGNAL 能够有效防止 Unix 系统在往断开的连接写入时触发致命的 SIGPIPE 信号崩溃进程 */ #ifdef MSG_NOSIGNAL ssize_t n = send(impl->sock, buf, (size_t)len, MSG_NOSIGNAL); #else ssize_t n = send(impl->sock, buf, (size_t)len, 0); #endif #endif if (n == C_SOCKET_ERROR) { if (bytes_written) *bytes_written = 0; return C_ERR_FAIL; } if (bytes_written) *bytes_written = (c_size_t)n; return ( (c_size_t)n == len ) ? C_SUCCESS : C_ERR_FAIL; } static c_err_t _SocketOut_Flush(c_OutStream_t* self) { /* TCP 套接字在操作系统内核层通常是实时刷新或通过 Nagle 算法控制,上层虚函数表在此可直接视为合规 */ (void)self; return C_SUCCESS; } static void _SocketOut_Destroy(c_OutStream_t* self) { c_SocketOutImpl_t* impl = (c_SocketOutImpl_t*)self; c_Allocator_t alloc = impl->allocator; c_Allocator_Free(&alloc, impl); } static const c_OutStreamVtbl_t g_SocketOutVtbl = { _SocketOut_Write, _SocketOut_Flush, _SocketOut_Destroy }; c_err_t c_SocketOutStream_Create(c_OutStream_t** out_stream, c_socket_t sock, c_Allocator_t* allocator) { if (!out_stream || sock == C_INVALID_SOCKET) return C_ERR_PARAM; c_Allocator_t alloc = allocator ? *allocator : c_DefaultAllocator; c_SocketOutImpl_t* impl = (c_SocketOutImpl_t*)c_Allocator_Calloc(&alloc, 1, sizeof(c_SocketOutImpl_t)); if (!impl) return C_ERR_NOMEM; impl->base.vtbl = &g_SocketOutVtbl; impl->sock = sock; impl->allocator = alloc; *out_stream = &impl->base; return C_SUCCESS; }