2

我正在尝试在 Windows 上的套接字上使用 fprintf。许多在线示例都是UNIX 示例。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();

当我运行它时,另一端没有任何结果(使用腻子),并且在 WSACleanup(); 处出现异常;WSACleanup 的例外是An invalid handle was specified.

更新通过更仔细地阅读这篇文章,我发现了一个强有力的领先优势。如果我更换:

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

fprintfsock(client, "Hello World\r\n");

有用。

不过,这仍然不是我问题的完整答案。我正在寻找直接使用 fprintf() 。

4

2 回答 2

4

A socket is not a file handle, so you cannot use _open_osfhandle() to wrap it. That is why fprintf() is not working. fprintfsock() is specifically designed to work with a socket directly. It is merely a wrapper that formats the data into a local buffer and then uses the socket API send() function to send it. If you really want to use fprintf() with a socket, you will have to #undef fprintf and then #define fprintf() to re-map it to fprintfsock() (which will only work if you are using a compiler that supports variadic macros). Otherwise, just use fprintfsock() directly.

于 2013-01-15T19:01:22.273 回答
0

我对使用 mingw 的套接字上的客户端部分 fprintf 也有类似的担忧,您应该尝试以非重叠模式创建套接字:

int sock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
于 2014-10-31T13:02:42.657 回答