mailslot好像是通过UDP来传输数据的,不太可靠
可以用Socket,还是跨平台的
可以用Socket,还是跨平台的
Windows中有两种基于虚拟文件系统的进程间通信方式——邮件槽和管道。邮件槽的优点是简单稳定,不会动不动就管道损坏,缺点是一次传输数据不能超过64kB,而且是单工模式,只能客户端发给服务器。不过我们可以手工实现有连接的双工通信。
客户端一般采用无限长等待方式,而服务端一般采用无等待循环检查的方式实现。
项目属性里的字符集设置为[使用多字节字符集]。
客户端:
<code class="language-cpp">#include <stdio.h> #include <windows.h> char appname[] = "myapp1"; int main() { char namebuf[1024] = ""; wsprintf(namebuf, "//./mailslot/%s/listen", appname); HANDLE hlisten; while (INVALID_HANDLE_VALUE == (hlisten = CreateFile(namebuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL))) { } DWORD threadid = GetCurrentThreadId(); DWORD writenum = 0; DWORD readnum = 0; int clientid = -1; DWORD sentnum = 0; wsprintf(namebuf, "//./mailslot/%s/%u/client", appname, threadid); HANDLE hclient = CreateMailslot(namebuf, 0, MAILSLOT_WAIT_FOREVER, NULL); WriteFile(hlisten, &threadid, sizeof threadid, &writenum, NULL); ReadFile(hclient, &clientid, sizeof clientid, &readnum, NULL); CloseHandle(hlisten); printf("connect established, connection id %d\n", clientid); wsprintf(namebuf, "//./mailslot/%s/%u/server", appname, threadid); HANDLE hserver = CreateFile(namebuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); WriteFile(hserver, "来自邮件槽客户端的问候", 22, &writenum, NULL); ReadFile(hclient, &sentnum, sizeof sentnum, &readnum, NULL); printf("sent %u bytes\n", sentnum); WriteFile(hserver, "\033disconnect", 11, &writenum, NULL); ReadFile(hclient, &sentnum, sizeof sentnum, &readnum, NULL); printf("sent %u bytes\n", sentnum); } </windows.h></stdio.h></code>
服务端:
<code class="language-cpp">#include <stdio.h> #include <windows.h> char appname[] = "myapp1"; HANDLE listen_handle; #define CONNECTION_NUM 16 HANDLE client_handle[CONNECTION_NUM]; HANDLE server_handle[CONNECTION_NUM]; int main() { char namebuf[1024] = ""; wsprintf(namebuf, "//./mailslot/%s/listen", appname); listen_handle = CreateMailslot(namebuf, 0, 0, NULL); if (listen_handle == INVALID_HANDLE_VALUE) { printf("ERR - cannot listen on %s\n", namebuf); return 1; } printf("SUC - listen on %s\n", namebuf); for (int i = 0; i < CONNECTION_NUM; i++) { client_handle[i] = INVALID_HANDLE_VALUE; server_handle[i] = INVALID_HANDLE_VALUE; } DWORD threadid = 0; DWORD readnum = 0; DWORD writenum = 0; while (true) { for (int i = 0; i < CONNECTION_NUM; i++) { if (client_handle[i] == INVALID_HANDLE_VALUE || server_handle == INVALID_HANDLE_VALUE) { CloseHandle(client_handle[i]); CloseHandle(server_handle[i]); client_handle[i] = INVALID_HANDLE_VALUE; server_handle[i] = INVALID_HANDLE_VALUE; ReadFile(listen_handle, &threadid, sizeof threadid, &readnum, NULL); if (readnum < sizeof threadid) continue; wsprintf(namebuf, "//./mailslot/%s/%u/client", appname, threadid); client_handle[i] = CreateFile(namebuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (client_handle[i] == INVALID_HANDLE_VALUE) { printf("ERR - connection %d cannot open %s\n", i, namebuf); continue; } SetMailslotInfo(client_handle[i], 0); printf("SUC - connection %d open %s\n", i, namebuf); wsprintf(namebuf, "//./mailslot/%s/%d/server", appname, threadid); server_handle[i] = CreateMailslot(namebuf, 0, 0, NULL); if (server_handle[i] == INVALID_HANDLE_VALUE) { printf("ERR - connection %d cannot create %s\n", i, namebuf); CloseHandle(client_handle[i]); client_handle[i] = INVALID_HANDLE_VALUE; continue; } printf("SUC - connection %d create %s\n", i, namebuf); WriteFile(client_handle[i], &i, sizeof i, &writenum, NULL); } else { char buf[65537] = ""; char msgbuf[1024] = ""; ReadFile(server_handle[i], buf, 65536, &readnum, NULL); if (readnum == 0) continue; printf("SUC - connection %d read %u bytes: %s\n", i, readnum, buf); WriteFile(client_handle[i], &readnum, sizeof readnum, &writenum, NULL); if (lstrcmpi(buf, "\033disconnect") == 0) { CloseHandle(client_handle[i]); CloseHandle(server_handle[i]); client_handle[i] = INVALID_HANDLE_VALUE; server_handle[i] = INVALID_HANDLE_VALUE; printf("SUC - connection %d closed\n", i); continue; } } } } } </windows.h></stdio.h></code>
[修改于 8年1个月前 - 2016/12/04 17:41:56]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。