C++迷你聊天应用程序
C++ mini chat App
所以我正在尝试创建一个迷你聊天应用程序,只是为了进入和理解套接字编程以及关于线程的一两件事,我正在使用 c++ Mfc 来做,我可以在客户端和服务器之间建立连接(使用 netstat 验证),但至于发送和 recv 函数,我不太明白应该怎么做, 我从客户端应用程序发送消息,但服务器似乎没有收到它
服务器源代码:
int RcvThread();
SOCKET s;
void CChat_ServerDlg::OnBnClickedButton2()
{
WSADATA w;
int error = WSAStartup ( 0x0202,&w);
if(error)
{
OnCancel();
}
if (w.wVersion != 0x0202)
{
WSACleanup ();
OnCancel();
}
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(DEFAULT_PORT);
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
OnCancel();
}
if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
OnCancel();
}
listen (s, SOMAXCONN);
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE) RcvThread, NULL, NULL, NULL);
int buffsize = 1024;
char msg[1024] = "a";
int marker;
}
int RcvThread()
{
char sbuffer[256];
char buffer[sizeof(sbuffer)] = {0};
for(;; )
{
if(recv(s, buffer, sizeof(sbuffer), NULL) > 0)
{
memcpy(&sbuffer, buffer, sizeof(sbuffer));
MessageBox(hnd,sbuffer,"message",NULL);
}
}
return 0;
}
客户的源代码:
SOCKET s;
void CChat_ClientDlg::OnBnClickedOk()
{
WSADATA wsadata;
int error = WSAStartup(0x0202,&wsadata);
if (error)
{
MessageBox("Error","ERRR");
OnCancel();
}
if (wsadata.wVersion != 0x0202)
{
WSACleanup ();
OnCancel();
}
SOCKADDR_IN target;
target.sin_family = AF_INET;
target.sin_port = htons(3124);
target.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
OnCancel();
}
if (connect(s, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
{
OnCancel();
}
}
按钮发送消息:
void CChat_ClientDlg::OnBnClickedButton2()
{
char* Msg = new char[256];
Msg = "abdouabdouabdou";
send(s,Msg,256,NULL);
}
您缺少套接字的基本概念。侦听套接字(代码中的 s)用于接受连接请求。它不用于发送/接收数据。您必须为此创建另一个套接字。您需要对文档和样本进行更多研究。一个来源是:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738545(v=vs.85).aspx
此外,您的线程不正确。如果使用 CreateThread,则线程函数必须与为 CreateThread 指定的签名匹配。但在MFC应用程序中,您应该使用AfxBeginThread而不是CreateThread。
首先,相信 send() 和 recv() 会发送和接收数据包是一个常见的误解。如果您使用 TCP(您应该用于聊天程序),recv() 可以返回 0 和您指定的缓冲区限制之间的任意数量的字节。因此,如果您发送 256 字节,您的 recv() 函数可以将其拆分为消息的两个、三个或更多片段,或者它可以返回第一条消息的结尾和第二条消息的开头。经常做的是消息的前 n 字节(n 取决于最大消息大小)标记消息的长度。由于您将协议限制为 256 字节的消息长度,因此 1 字节就足够了。收到第一个字节后,分配一个与您的消息一样大的消息缓冲区,并将 recv() 放入...井。。。接收循环,直到它收到整个消息。您需要在接收缓冲区等中处理偏移量。
其次,你不太了解 bind()/listen()/accept() 系统是如何工作的。listen() 函数将套接字设置为被动模式,在该模式下它正在侦听新客户端。accept() 最终建立与新客户端的连接并返回一个新的套接字,然后用于与客户端通信。原始(侦听)套接字继续侦听新客户端。
第三,发送函数处理字符缓冲区不正确。我根据我的建议更正了一下(消息的第一个字节标记以下消息的长度):
void CChat_ClientDlg::OnBnClickedButton2()
{
std::string myMessage = "abdouabdouabdou";
unsigned char buffer[256];
buffer[0] = (unsigned char)myMessage.length();
memcpy(buffer+1, myMessage.c_str(), std::min(myMessage.length(), 255));
send(s, buffer, 256, NULL);
}
即使该方法也是不正确的,因为 send() 返回的字节数可能小于我的缓冲区大小,尽管对于这种小消息来说这种情况很少见。
- 试图在visual studio上用C++创建一个桌面应用程序
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 在C应用程序中运行C++(带有STL)函数
- 使用VerQueryValue检索应用程序的文件描述
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 使用调试/崩溃报告将应用程序部署到客户端
- C++控制台应用程序阻止退出
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 将应用程序从32位移植到64位时出现问题
- 如何改变c++应用程序的视觉效果
- WM_CTLCOLORSTATIC从未在WIN32应用程序中触发
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- C++客户端/服务器聊天应用程序 - 从 Ubuntu 命令窗口扫描输入
- 如何在桌面应用程序中使用WEBRTC进行语音聊天
- 聊天应用程序-从客户端连接到服务器时出现故障
- 两台具有相同 IP 地址的计算机 - 使用套接字的聊天应用程序
- 如何在小型聊天应用程序中为数据库存储的用户事务建模
- 如何在C++聊天应用程序中放置昵称
- C++迷你聊天应用程序
- 基于共享内存的聊天应用程序的问题