これは単純なクライアントソケットアプリケーションです。このコードを実行すると、サーバーはデータを受信すると空のバッファーを受信します。誰でも問題を見つけることができますか? コードは、ソケットを使用してデータを転送するcppで記述されます。 接続後、クライアントは「Hello im client」をサーバーに送信することになっており、サーバーはメッセージを出力しますが、何らかの問題があります。
これはサーバーコードです
#define IP "127.0.0.1"
int ConnectServer::connectTo()
{
//----------------------
// Initialize Winsock
WSADATA wsaData;
int iResult = 0;
_ListenSocket = INVALID_SOCKET;
sockaddr_in serverAddr;
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup() failed with error: %d\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for listening for incoming connection requests.
_ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_ListenSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(PORT);
iResult = bind(_ListenSocket, (SOCKADDR*)& serverAddr, sizeof(serverAddr));
if (iResult == SOCKET_ERROR) {
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
iResult = closesocket(_ListenSocket);
if (iResult == SOCKET_ERROR)
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// Listen for incoming connection requests
// on the created socket
if (listen(_ListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
closesocket(_ListenSocket);
WSACleanup();
return 1;
}
// Create a SOCKET for accepting incoming requests.
SOCKET AcceptSocket;
sockaddr_in client;
wprintf(L"Waiting for client to connect...\n");
//----------------------
// Accept the connection.
int clientSize = sizeof(client);
AcceptSocket = accept(_ListenSocket, (SOCKADDR*)&client, &clientSize);
if (AcceptSocket == INVALID_SOCKET)
{
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(_ListenSocket);
WSACleanup();
return 1;
}
else
{
wprintf(L"Client connected.\n");
}
//cout << "whats happening??" << endl;
char* buffer = "";
iResult = recv(AcceptSocket, buffer, (int)strlen(buffer), 0);
if (iResult == SOCKET_ERROR) {
printf("recv function failed with error: %d\n", WSAGetLastError());
closesocket(_server);
WSACleanup();
return 1;
}
else
{
printf("recieved data:\n");
printf(buffer);
}
iResult = closesocket(_ListenSocket);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
{
std::cout << "Client disconnected" << std::endl;
}
WSACleanup();
return 0;
}
これはクライアントコードです:
int ConnectClient::connectTo()
{
int iResult;
WSADATA WSAData;
SOCKET _server;
SOCKADDR_IN addr;
HBITMAP pic = NULL;
WSAStartup(MAKEWORD(2, 0), &WSAData);
_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_addr.s_addr = inet_addr(IP);
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
if (connect(_server, (SOCKADDR *)&addr, sizeof(addr)) == INVALID_SOCKET)
{
wprintf(L"connect function failed with error: %d\n", WSAGetLastError());
system("PAUSE");
return 1;
}
else{
std::cout << "Connected to _server!" << std::endl;
char *Buffer = "hello I'm client";
printf(Buffer);
iResult = send(_server, Buffer, (int)strlen(Buffer), 0);
if (iResult == SOCKET_ERROR) {
printf("send failed: %d\n", WSAGetLastError());
closesocket(_server);
WSACleanup();
return 1;
}
}
//cout << testBuffer << endl;
//cout << strlen(testBuffer) << endl;
//coordinations(_server);
iResult = closesocket(_server);
if (iResult == SOCKET_ERROR) {
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
{
std::cout << "Client disconnected" << std::endl;
}
WSACleanup();
std::cout << "Socket closed." << std::endl << std::endl;
system("PAUSE");
return 0;
}
int ConnectClient::coordinations(SOCKET server)
{
HANDLE hStdInput, hStdOutput, hEvent; //WAIT_ABANDONED = 128
INPUT_RECORD ir[128]; //WAIT_OBJECT_0 = 0
DWORD nRead; //WAIT_TIMEOUT = 258
COORD xy;
UINT i;
hStdInput = GetStdHandle(STD_INPUT_HANDLE);
hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
FlushConsoleInputBuffer(hStdInput);
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //Event is created non-signaled (3rd param).
HANDLE handles[2] = { hEvent, hStdInput };
//char testBuffer[1024];
char a;
char b;
//Program loops monitoring two handles. The
while (WaitForMultipleObjects(2, handles, FALSE, INFINITE)) //1st handle ( handles(0) ) is an event which
{ //is initially set to non-signaled. The 2nd
ReadConsoleInput(hStdInput, ir, 128, &nRead); //handle monitored by WaitForMultipleObjects()
for (i = 0; i<nRead; i++) //is the standard input handle set up to
{ //allow access to mouse/keyboard input. As
switch (ir[i].EventType) //long as neither handle is in a signaled
{ //state, WaitForMultipleObjects() will block
case KEY_EVENT: //in an efficient wait state. If any keypress
if (ir[i].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) //or mouse movement occurs, WaitForMultiple
SetEvent(hEvent); //Objects will return TRUE and the input will
else //be read by ReadConsolInput(). If the [ESCAPE]
{ //key is pressed the event object represented
xy.X = 0; xy.Y = 0;
//by hEvent will be set to a signaled state by
SetConsoleCursorPosition(hStdOutput, xy); //the SetEvent() Api function. This will be
printf //picked up by the next WaitForMultipleObjects()
(
//call, and the function will return FALSE and
"AsciiCode = %d: symbol = %c\n", //execution will drop out of the while loop
ir[i].Event.KeyEvent.uChar.AsciiChar, //and program termination will occur.
ir[i].Event.KeyEvent.uChar.AsciiChar
);
a = ir[i].Event.KeyEvent.uChar.AsciiChar;
b = ir[i].Event.KeyEvent.uChar.AsciiChar;
char testBuffer[1024] = "AsciiCode = %d: symbol = %c\n", a, b; //execution will drop out of the while loop
//and program termination will occur.
send(server, testBuffer, strlen(testBuffer), 0);//It is important to note that if the 3rd
} //parameter to WaitForMultipleObjects() is
break; //set to FALSE, the function will return if
case MOUSE_EVENT: //either of the handles in the HANDLE array
xy.X = 0, xy.Y = 1; //represented by handles is signaled.
SetConsoleCursorPosition(hStdOutput, xy);
printf
(
"%.3d\t%.3d\t%.3d",
ir[i].Event.MouseEvent.dwMousePosition.X,
ir[i].Event.MouseEvent.dwMousePosition.Y,
(int)ir[i].Event.MouseEvent.dwButtonState & 0x07 //mask out scroll wheel, which screws up
); //output
a = ir[i].Event.MouseEvent.dwMousePosition.X;
b = ir[i].Event.MouseEvent.dwMousePosition.Y;
char testBuffer[1024] = "AsciiCode = %d: symbol = %c\n", a, b; //execution will drop out of the while loop
//and program termination will occur.
send(server, testBuffer, strlen(testBuffer), 0);
break;
}
}
};
return 0;
}
回答 1 件
関連記事
- アプリケーションシングルトンを作成するJavaの簡単な方法
- 非同期サンプルクライアントソケット受信ループ
- ChromeデバッガーでVS Codeのプロキシを介してAngularクライアントアプリケーションをデバッグする方法
- 単純なSparkアプリケーションの動作が非常に遅いのはなぜですか?
- クライアント側がソケットに接続できません
- Grailsでの超単純なテストの作成に関する問題
- C#アプリケーションからHPC 2016クライアントDLLにリンクするにはどうすればよいですか?
- PHPクライアントからPHP Webサーバーソケットにデータを送信する
- Laravel AWS Simple Email ServiceエラーSignatureDoesNotMatch(クライアント):計算したリクエスト署名は、指定した署名と一致しません。
問題はここにあります:
あなたは
recv
に言っているbuffer
としてゼロバイトを読み取る 空です。さらに、コードにはいくつかの問題があります。次のような文字列を送信しています:
これはすべての文字を送信しますが、nullターミネーターは送信しません。ただし、サーバーコードは
printf
を介してコードを出力するため、ヌルターミネータが必要です。 。より重要な問題は、データの送信方法です。サーバーは、クライアントから送信されるデータの量を把握していないため、一度に1バイトを読み取らない限り、ヌルターミネータ(非常に非効率的)を取得するまで問題が発生します。
これに対する通常のアプローチは、固定サイズのメッセージヘッダーを送信し、サーバーにヘッダーを読み取らせることです。ヘッダーのフィールドの1つにメッセージ本文の長さが含まれ、サーバーがヘッダーを読み取ると、メッセージ本文にメモリを割り当ててから読み取ることができます。