C 在Windows中的套接字上使用fprintf

C 在Windows中的套接字上使用fprintf,c,sockets,winapi,winsock,msvcrt,C,Sockets,Winapi,Winsock,Msvcrt,我正在尝试在Windows上的套接字上使用fprintf。许多在线示例如下所示。Windows的等效代码就是我在这里要问的 最后,我想这样做: fprintf(file_handle_to_socket, "hello world\r\n"); 我不想使用WriteFile、snprintf或其他任何东西。只是fprintf 或多或少显示步骤的伪代码将很有帮助 以下是我到目前为止的情况: unsigned short port = enter_port; int result = 0; WS

我正在尝试在Windows上的套接字上使用fprintf。许多在线示例如下所示。Windows的等效代码就是我在这里要问的

最后,我想这样做:

fprintf(file_handle_to_socket, "hello world\r\n");
我不想使用WriteFile、snprintf或其他任何东西。只是fprintf

或多或少显示步骤的伪代码将很有帮助

以下是我到目前为止的情况:

unsigned short port = enter_port;

int result = 0;
WSADATA wsaData;
result = WSAStartup(MAKEWORD(2, 2), &wsaData);

struct sockaddr_in local;
memset(&local, 0, sizeof(struct sockaddr_in));

local.sin_port = htons(port);
local.sin_family = AF_INET;
local.sin_addr.s_addr = htonl(INADDR_ANY);

int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == INVALID_SOCKET)
{
    fprintf(stdout,"invalid socket: error code %d\n", WSAGetLastError());
}

result = bind(sock, (struct sockaddr*)&local, sizeof(struct sockaddr_in));
if(result == SOCKET_ERROR)
{
    fprintf(stdout,"bind() failed: error code %d\n", WSAGetLastError());
}

result = listen(sock, 5);

struct sockaddr peer;
memset(&peer, 0, sizeof(struct sockaddr));

SOCKET client = 0;
int size = sizeof(struct sockaddr);
client = accept(sock, &peer, &size);

int OSFileHandle = _open_osfhandle(client, _O_APPEND);
FILE * file_handle_to_socket = fdopen(OSFileHandle, "w+");

fprintf(file_handle_to_socket, "Hello World\r\n");

// hoping this helps -- it doesn't
fflush(file_handle_to_socket);

fclose(file_handle_to_socket);
closesocket(client);

// this throws an exception
WSACleanup();
当我运行这个程序时,在另一端使用putty时没有任何结果,我在WSACleanup得到一个异常;WSACleanup处的异常是指定了无效句柄

更新我发现一个强大的领导更密切。 如果我替换:

fprintf(file_handle_to_socket, "Hello World\r\n");

它起作用了


但这仍然不是我问题的完整答案。我希望直接使用fprintf。

套接字不是文件句柄,因此不能使用_open_osf句柄来包装它。这就是fprintf不起作用的原因。fprintfsock是专门设计用于直接使用套接字的。它只是一个包装器,将数据格式化为本地缓冲区,然后使用socket API发送函数发送数据。如果您确实想将fprintf与套接字一起使用,则必须先取消fprintf的定义,然后定义fprintf以将其重新映射到fprintfsock,只有在使用支持可变宏的编译器时,fprintf才会起作用。否则,直接使用fprintfsock即可。

套接字不是文件句柄,因此不能使用_open_osf句柄包装它。这就是fprintf不起作用的原因。fprintfsock是专门设计用于直接使用套接字的。它只是一个包装器,将数据格式化为本地缓冲区,然后使用socket API发送函数发送数据。如果您确实想将fprintf与套接字一起使用,则必须先取消fprintf的定义,然后定义fprintf以将其重新映射到fprintfsock,只有在使用支持可变宏的编译器时,fprintf才会起作用。否则,直接使用fprintfsock即可。

我对客户端部件也有类似的问题,您应该尝试在非重叠模式下创建套接字:

int sock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);

我对客户端部件也有类似的担忧,您应该尝试在非重叠模式下创建套接字:

int sock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);

如何声明和填写自己的文件结构,该结构使用自己的回调在内部调用send和recv?没有这样做的函数调用吗?像fdopen?不,没有函数可以使用自定义回调设置文件结构。事实上,现在我想起来了,这无论如何都不会起作用,因为fprintf将在内部调用文件I/O函数,这些函数期望文件*最终映射到真实的文件,而套接字不是。因此,您可能根本无法将fprintf与套接字I/O一起使用。只需使用fprintfsock即可。如何声明并填写自己的文件结构,该结构使用自己的回调在内部调用send和recv?没有这样做的函数调用吗?像fdopen?不,没有函数可以使用自定义回调设置文件结构。事实上,现在我想起来了,这无论如何都不会起作用,因为fprintf将在内部调用文件I/O函数,这些函数期望文件*最终映射到真实的文件,而套接字不是。因此,您可能根本无法将fprintf与套接字I/O一起使用。只需使用fprintfsock即可。