C++Winsock将冻结接收数据
C++ Winsock Will Freeze Receiving Data
我正在用C++中的Code::Blocks制作一个程序,用Winsocks发送和接收数据,但当我试图接收数据时,我的程序会冻结,请帮忙。我不知道为什么?我在不使用循环的情况下只能得到1行,所以我添加了一个循环,看看是否可以得到更多的行,现在它就冻结了。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "resource.h"
#include <winsock.h>
using namespace std;
SOCKET mysocket;
SOCKADDR_IN SockAddr;
char buf1[120];
char buf2[120];
char ReadIp[120];
int UsePort;
int n;
HINSTANCE hInst;
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
WSADATA WsaDat;
WSAStartup(MAKEWORD(1,1), &WsaDat);
mysocket = socket(AF_INET, SOCK_STREAM, 0);
return TRUE;
case WM_CLOSE:
EndDialog(hwndDlg, 0);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BTN_QUIT:
EndDialog(hwndDlg, 0);
return TRUE;
case BtnSend:
GetDlgItemText(hwndDlg, PacketText, buf2, sizeof(buf2));
send(mysocket, buf2, sizeof(buf2), 0);
return TRUE;
case IDC_BTN_TEST:
UsePort = GetDlgItemInt(hwndDlg, PortText, NULL, FALSE);
GetDlgItemText(hwndDlg, IpText, ReadIp, sizeof(ReadIp));
SockAddr.sin_port = htons(UsePort);
SockAddr.sin_addr.s_addr=inet_addr(ReadIp);
SockAddr.sin_family = AF_INET;
connect(mysocket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr));
do {
n = recv(mysocket, buf1, sizeof(buf1), 0);
if (n > 0)
SetDlgItemText(hwndDlg, List1, buf1);
} while (n > 0);
return TRUE;
}
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
hInst = hInstance;
// The user interface is a modal dialog box
return DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
}
它冻结是因为它在等待数据。如果您不想等待数据,请不要进行Winsock调用。使用Windows上可用的许多非阻塞I/O方法之一,如异步操作、I/O完成端口或完成事件。
顺便说一句,你的代码在很多方面都被严重破坏了。它似乎缺少协议。如果不在TCP之上设计和实现一个协议,就无法使用TCP。如果你不通过某种重建传输信息的协议引擎来处理你收到的数据,你将得到完全不可靠的行为。例如,在您的案例中,如果有人发送"foo",那么最终的文本将取决于数据是如何组装以进行传输的。它可能是"foo",但可能是"o",因为"fo"可以被覆盖。
如果另一方正在发送行,正如您所声称的,您需要将此端编码为接收行。也就是说,你需要一直接收数据,直到你有了一条线路,不要让以后的接收覆盖以前的接收,这样你就可以重新组装传输的线路。实际实现接收行的代码在您粘贴的代码中完全缺失。(例如,如果"行"被定义为以换行符结尾的一组字节,则需要有代码来搜索换行符,并将它们之前的所有内容组装到一个缓冲区中进行处理。)
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- C++Winsock将冻结接收数据
- C++程序在试图显示一个顶点从数据文件中读取的三角形时会冻结
- 如何在不被操作系统冻结或杀死进程的情况下向文件写入大量数据