Socket recv() 将我的字符串变成了 char "C:\User" 'C'
Socket recv() made my string into a char "C:\User" 'C'
为什么字符串 a return 'C' 而不是 "C:\Users\Desktop\Project phoneedge\ForMark\Top"?
当我在一个空的 c++ 项目中测试它时,在我将我的一些代码从 ThreadFunction 移动到 StartButton 之前它工作了(UI 应该不断更新但是套接字 recv() 正在阻塞它导致它只更新一次所以我将 UI 代码移动到 startbutton)
这是服务器代码,按下开始按钮后,启动套接字并创建一个线程来 运行 listen() accept() 和 recv()。关闭按钮关闭套接字和线程。
服务器代码(MFC项目)
void CUIServerDlg::StartButton()
{
WSADATA Winsockdata;
int iTCPClientAdd = sizeof(TCPClientAdd);
WSAStartup(MAKEWORD(2, 2), &Winsockdata);
TCPServerAdd.sin_family = AF_INET;
TCPServerAdd.sin_addr.s_addr = inet_addr("127.0.0.1");
TCPServerAdd.sin_port = htons(8000);
TCPServersocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(TCPServersocket, (SOCKADDR*)&TCPServerAdd, sizeof(TCPServerAdd));
bRunning = true;
hthread = CreateThread(NULL, 0, ThreadFunction, this, 0, &ThreadID);
WaitForSingleObject(hthread, INFINITE);
funRunning = true;
while (funRunning == true) {
vector<string> caseOne;
/*string a;
char RecvBuffer[512];//this is the declaration in member class
int iRecvBuffer = strlen(RecvBuffer) + 1;*/
**a = RecvBuffer;**//a is a String, RecvBuffer is a path name like c:\user..
//Find files,This part of code is left out because it should not effect the question
//put the files found in a vector, then display it on a listbox
for (string fileVec : caseOne) {
CString fileunderPath;
string filevector1 = fileVec;
fileunderPath = filevector1.c_str();//conversion for AddString
list1.AddString(fileunderPath);
}
Sleep(1000);//The code updates every 1 second , when file names are modified is displays immediately.
}
}
我想将 Sleep(1000) 更改为 WaitForSingleObject() 以替换 WM_Timer 用于分配,但我不知道如何,因为您需要一个句柄,我是否创建另一个线程?
void CUIServerDlg::CloseButton()
{
bRunning = false;
funRunning = false;
WaitForSingleObject(hthread, INFINITE);
CloseHandle(hthread);
closesocket(TCPServersocket);
}
所以在这个项目之前我从来没有学过任何关于套接字和线程的知识,下面代码的想法是使用一个线程来运行一个while循环来不断地检查新的客户端来发送东西,如果思路有误,请务必指正。
DWORD WINAPI CUIServerDlg::ThreadFunction(LPVOID lpParam) {
CUIServerDlg* This = (CUIServerDlg*)lpParam;
while (This->bRunning == true) {
int iListen = listen(This->TCPServersocket, 10);
if (iListen == INVALID_SOCKET)
OutputDebugString(_T("FAIL LISTEN\n"));
This->sAccecpSocket = accept(This->TCPServersocket, (SOCKADDR*)&This->iTCPClientAdd, &This->iTCPClientAdd);
recv(This->sAccecpSocket, This->RecvBuffer, This->iRecvBuffer, 0);
}
return 0;
}
客户端代码(空 c++ 项目)
int main(){
string a = "C:\Users\Desktop\Project phoneedge\ForMark\Top";
const char* SenderBuffer = a.c_str();
int iSenderBuffer = strlen(SenderBuffer) + 1;
WSAStartup(MAKEWORD(2, 2), &WinSockData);
TCPClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
TCPServerAdd.sin_family = AF_INET;
TCPServerAdd.sin_addr.s_addr = inet_addr("127.0.0.1");
TCPServerAdd.sin_port = htons(8000);
connect(TCPClientSocket,(SOCKADDR*)&TCPServerAdd,sizeof(TCPServerAdd));
send(TCPClientSocket, SenderBuffer, iSenderBuffer, 0);
closesocket(TCPClientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
TCP协议以字节流方式传递数据。
意思是客户端一个字节一个字节的传递数据,而不是一次传递所有的数据。
当您收到来自客户端的数据时。过关手续可能还没有完成
因此需要调用一次recv
调用接收到部分数据后检查数据是否传递完毕,然后保存子数据,直到接收到所有数据。
为什么字符串 a return 'C' 而不是 "C:\Users\Desktop\Project phoneedge\ForMark\Top"?
当我在一个空的 c++ 项目中测试它时,在我将我的一些代码从 ThreadFunction 移动到 StartButton 之前它工作了(UI 应该不断更新但是套接字 recv() 正在阻塞它导致它只更新一次所以我将 UI 代码移动到 startbutton)
这是服务器代码,按下开始按钮后,启动套接字并创建一个线程来 运行 listen() accept() 和 recv()。关闭按钮关闭套接字和线程。
服务器代码(MFC项目)
void CUIServerDlg::StartButton()
{
WSADATA Winsockdata;
int iTCPClientAdd = sizeof(TCPClientAdd);
WSAStartup(MAKEWORD(2, 2), &Winsockdata);
TCPServerAdd.sin_family = AF_INET;
TCPServerAdd.sin_addr.s_addr = inet_addr("127.0.0.1");
TCPServerAdd.sin_port = htons(8000);
TCPServersocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(TCPServersocket, (SOCKADDR*)&TCPServerAdd, sizeof(TCPServerAdd));
bRunning = true;
hthread = CreateThread(NULL, 0, ThreadFunction, this, 0, &ThreadID);
WaitForSingleObject(hthread, INFINITE);
funRunning = true;
while (funRunning == true) {
vector<string> caseOne;
/*string a;
char RecvBuffer[512];//this is the declaration in member class
int iRecvBuffer = strlen(RecvBuffer) + 1;*/
**a = RecvBuffer;**//a is a String, RecvBuffer is a path name like c:\user..
//Find files,This part of code is left out because it should not effect the question
//put the files found in a vector, then display it on a listbox
for (string fileVec : caseOne) {
CString fileunderPath;
string filevector1 = fileVec;
fileunderPath = filevector1.c_str();//conversion for AddString
list1.AddString(fileunderPath);
}
Sleep(1000);//The code updates every 1 second , when file names are modified is displays immediately.
}
}
我想将 Sleep(1000) 更改为 WaitForSingleObject() 以替换 WM_Timer 用于分配,但我不知道如何,因为您需要一个句柄,我是否创建另一个线程?
void CUIServerDlg::CloseButton()
{
bRunning = false;
funRunning = false;
WaitForSingleObject(hthread, INFINITE);
CloseHandle(hthread);
closesocket(TCPServersocket);
}
所以在这个项目之前我从来没有学过任何关于套接字和线程的知识,下面代码的想法是使用一个线程来运行一个while循环来不断地检查新的客户端来发送东西,如果思路有误,请务必指正。
DWORD WINAPI CUIServerDlg::ThreadFunction(LPVOID lpParam) {
CUIServerDlg* This = (CUIServerDlg*)lpParam;
while (This->bRunning == true) {
int iListen = listen(This->TCPServersocket, 10);
if (iListen == INVALID_SOCKET)
OutputDebugString(_T("FAIL LISTEN\n"));
This->sAccecpSocket = accept(This->TCPServersocket, (SOCKADDR*)&This->iTCPClientAdd, &This->iTCPClientAdd);
recv(This->sAccecpSocket, This->RecvBuffer, This->iRecvBuffer, 0);
}
return 0;
}
客户端代码(空 c++ 项目)
int main(){
string a = "C:\Users\Desktop\Project phoneedge\ForMark\Top";
const char* SenderBuffer = a.c_str();
int iSenderBuffer = strlen(SenderBuffer) + 1;
WSAStartup(MAKEWORD(2, 2), &WinSockData);
TCPClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
TCPServerAdd.sin_family = AF_INET;
TCPServerAdd.sin_addr.s_addr = inet_addr("127.0.0.1");
TCPServerAdd.sin_port = htons(8000);
connect(TCPClientSocket,(SOCKADDR*)&TCPServerAdd,sizeof(TCPServerAdd));
send(TCPClientSocket, SenderBuffer, iSenderBuffer, 0);
closesocket(TCPClientSocket);
WSACleanup();
system("PAUSE");
return 0;
}
TCP协议以字节流方式传递数据。
意思是客户端一个字节一个字节的传递数据,而不是一次传递所有的数据。
当您收到来自客户端的数据时。过关手续可能还没有完成
因此需要调用一次recv
调用接收到部分数据后检查数据是否传递完毕,然后保存子数据,直到接收到所有数据。