클라이언트 서버 프로그램의 일부 코드를 얻었고 직접 수정했습니다. 하지만 내 코드가 제대로 작동하지 않는 이유를 찾을 수 없습니다. 컴파일은 괜찮지 만 클라이언트에서 중단 오류가 발생합니까? 나는 자신을 시험해 보았고 프로그래밍에 익숙하지 않았습니다. 아래의 클라이언트 서버 코드를 살펴보고 proble이 무엇인지 확인하십시오.내 클라이언트 서버 코드가 올바르게 작동하지 않습니다.
//Client side code
#include <iostream>
#include <winsock2.h>
#include <vector>
#include <algorithm>
#include <ctime>
#include "client.h"
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
tcp_client::tcp_client()
{}
tcp_client::~tcp_client()
{}
int tcp_client::start_listening()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET ConnectSocket;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET)
{
cout<<"Client: Error at socket(): %ld.\n"<< WSAGetLastError();
WSACleanup();
return 0;
}
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
clientService.sin_port = htons(55555);
if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
cout<<"Client: Failed to connect\0";
WSACleanup();
return 0;
}
return 0;
}
int tcp_client::start_sending()
{
int bytesSent;
int bytesRecv = SOCKET_ERROR;
std::vector<double> m_vector;
uint32_t nlength =0;
std::vector<double> m_vector1(nlength/sizeof(double));
for(int i = 0; i <100; i++)
{
m_vector.push_back(i);
}
uint32_t siz = (m_vector.size())*sizeof(double);
int total_bytes = 0;
int count=0;
for(int j=0; j<10; j++)
{
bytesSent = send(ConnectSocket,(char*)&siz, 4, 0);
assert (bytesSent == sizeof (uint32_t));
std::cout<<"length information is in:"<<bytesSent<<"bytes"<<std::endl;
bytesSent = send(ConnectSocket,(char*)m_vector.data(), siz, 0);
total_bytes = total_bytes+bytesSent;
std::cout<<"Client: Bytes sent:"<<total_bytes<<std::endl;
}
closesocket (ConnectSocket);
return 0;
}
int main()
{
std::clock_t c_start = std::clock();
tcp_client a;
a.start_listening();
a.start_sending();
std::clock_t c_end = std::clock();
std::cout << "CPU time used: "<< 1000.0 * (c_end-c_start)/CLOCKS_PER_SEC<< " ms\n";
WSACleanup();
system("pause");
return 0;
}
// Client.h
#include <string.h>
#include <winsock2.h>
class tcp_client
{
public:
tcp_client();
virtual ~tcp_client();
int start_listening();
int start_sending();
protected:
SOCKET ConnectSocket; // client Socket
};
// 서버 코드
#include <iostream>
#include <winsock2.h>
#include <vector>
#include <algorithm>
#include <ctime>
#pragma comment(lib, "Ws2_32.lib")
#include "server.h"
using namespace std;
tcp_server::tcp_server()
{}
tcp_server::~tcp_server()
{}
int tcp_server::start_listening()
{
WORD wVersionRequested;
WSADATA wsaData;
int wsaerr;
wVersionRequested = MAKEWORD(2, 2);
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
std::cout<<"server starting...."<<std::endl;
}
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == INVALID_SOCKET)
{
cout<<"Server: Error at socket(): "<<WSAGetLastError()<<std::endl;
WSACleanup();
return 0;
}
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(55555);
if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
{
cout<<"Server: bind() failed:"<< WSAGetLastError();
closesocket(m_socket);
return 0;
}
if (listen(m_socket, 10) == SOCKET_ERROR)
{
cout<<"Server: listen(): Error listening on socket "<< WSAGetLastError()<<std::endl;
}
SOCKET AcceptSocket;
while (1)
{
AcceptSocket = SOCKET_ERROR;
while (AcceptSocket == SOCKET_ERROR)
{
AcceptSocket = accept(m_socket, NULL, NULL);
}
cout<<"Server: Client Connected"<<std::endl;
m_socket = AcceptSocket;
break;
}
return 0;
}
int tcp_server::start_receiving()
{
int bytesSent;
int bytesRecv;
uint32_t nlength =0;
int total_br =0;
std::vector<double> m_vector(nlength/sizeof(double));
std::clock_t c_start=0;
int count =0;
while(1)
{
int length_received = recv(m_socket,(char*)&nlength, 4, 0);
m_vector.resize(nlength/sizeof(double));
bytesRecv = recv(m_socket,(char*)m_vector.data(), nlength, 0);
if(bytesRecv > 0)
{
total_br = total_br + bytesRecv;
cout<<"Server: Received bytes are"<<total_br<<std::endl;
}
else
{
std::cout<<"Data Receiving has finished"<<std::endl;
break;
}
}
closesocket (m_socket);
WSACleanup();
return total_br;
}
int main()
{
std::clock_t c_start = std::clock();
tcp_server a;
a.start_listening();
int byte= a.start_receiving();
std::cout<<"total byte received are"<<byte;
std::clock_t c_end = std::clock();
std::cout << "CPU time used: "<< 1000.0 * (c_end-c_start)/CLOCKS_PER_SEC<< " ms\n";
system("pause");
return 0;
}
//server.h
#include <string.h>
#include <winsock2.h>
class tcp_server
{
public:
tcp_server();
virtual ~tcp_server();
int start_listening();
int start_receiving();
protected:
SOCKET m_socket; // Server Socket
};
서버 코드에 보안 취약점이 있습니다. 서버 포트에 연결하여 nLength에 0xffffffff를 보내면 코드가 후속 m_vector.resize 호출에 4GB를 할당하려고 시도합니다. 또한 recv()는 부분 데이터를 반환 할 수 있고 반환 할 수 있습니다. 모든 바이트를받을 때까지 recv()를 호출하는 루프를 반복해야합니다. 또는 MSG_WAIT 플래그를 사용하십시오. – selbie
어떻게 프로그램을 실행합니까? – jfly
@selbie MSG_WAITALL 플래그로 시도했지만 결과는 동일합니다. 내 질문은 내가 클라이언트에서 매번 길이와 데이터를 보내는 경우 서버가 매번 접두어 길이가있는 데이터를받지 못하는 이유는 무엇입니까? 왜 나는 단지 recv를 루프로 호출해야 하는가? 왜 length recv가 아닌가? 그 이유는 많은 데이터가 수신 될 수있는 것보다 길이가 판독 될 때 그 데이터가 separte가 아니기 때문입니다. 가능한 경우 실수를 정정 해 주실 수 있습니까? 이 코드는 클래스 없이는 잘 작동하지만 클래스로 구현 한 후에는 문제가 있습니다. – user3369727