_open_osfhandleしてfdopenすれば使えると思ったのに。
追ってみると、ReadFileでコケてるみたい。
ひょっとしてサーバ側だと使えないのかな?うーん…
socketじゃなくてWSASocketを使ったらできた!
#include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #define ECHO_PORT 7 #define MAX_BACKLOG 5 #define RCVBUFSIZE 255 #define die(...) do { fprintf(stderr, __VA_ARGS__); WSACleanup(); exit(1); } while(0) #define debug(...) do { fprintf(stderr, __VA_ARGS__); } while(0) static void wsa_startup(WORD version) { int n; WSADATA wsaData; if ((n = WSAStartup(version, &wsaData)) != 0) { die("WASStartup(): %d\n", n); } if (version != wsaData.wVersion) { die("WASStartup(): WinSock version %d.%d not supported\n", LOWORD(version), HIWORD(version)); } } void echo(FILE *f) { while (1) { char buf[RCVBUFSIZE + 1]; if (fgets(buf, RCVBUFSIZE + 1, f) == NULL) { break; } debug("recv: %s\n", buf); errno = 0; if (fputs(buf, f) == EOF) { if (errno != 0) { die("fputs()\n"); } } } } int main() { SOCKET sock, s; struct sockaddr_in addr, caddr; int len; wsa_startup(MAKEWORD(2, 0)); if ((sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0)) == INVALID_SOCKET) { die("socket(): %d\n", WSAGetLastError()); } addr.sin_family = AF_INET; addr.sin_port = htons(ECHO_PORT); addr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) != 0) { die("bind(): %d\n", WSAGetLastError()); } if (listen(sock, MAX_BACKLOG) != 0) { die("listen(): %d\n", WSAGetLastError()); } while(1) { int fd; FILE *f; len = sizeof(caddr); if ((s = accept(sock, (struct sockaddr *) &caddr, &len)) == INVALID_SOCKET) { die("accept(): %d\n", WSAGetLastError()); } debug("accepted.\n"); if ((fd = _open_osfhandle(s, O_RDWR|O_BINARY)) < 0) { die("_open_osfhandle()\n"); } if ((f = _fdopen(fd, "rb+")) == NULL) { die("_fdopen()\n"); } setvbuf(f, NULL, _IONBF, 0); echo(f); closesocket(s); debug("closed.\n"); } WSACleanup(); return 0; }