2014-03-03 2 views
1

클라이언트 서버 프로그램의 일부 코드를 얻었고 직접 수정했습니다. 하지만 내 코드가 제대로 작동하지 않는 이유를 찾을 수 없습니다. 컴파일은 괜찮지 만 클라이언트에서 중단 오류가 발생합니까? 나는 자신을 시험해 보았고 프로그래밍에 익숙하지 않았습니다. 아래의 클라이언트 서버 코드를 살펴보고 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 
    }; 
+3

서버 코드에 보안 취약점이 있습니다. 서버 포트에 연결하여 nLength에 0xffffffff를 보내면 코드가 후속 m_vector.resize 호출에 4GB를 할당하려고 시도합니다. 또한 recv()는 부분 데이터를 반환 할 수 있고 반환 할 수 있습니다. 모든 바이트를받을 때까지 recv()를 호출하는 루프를 반복해야합니다. 또는 MSG_WAIT 플래그를 사용하십시오. – selbie

+0

어떻게 프로그램을 실행합니까? – jfly

+0

@selbie MSG_WAITALL 플래그로 시도했지만 결과는 동일합니다. 내 질문은 내가 클라이언트에서 매번 길이와 데이터를 보내는 경우 서버가 매번 접두어 길이가있는 데이터를받지 못하는 이유는 무엇입니까? 왜 나는 단지 recv를 루프로 호출해야 하는가? 왜 length recv가 아닌가? 그 이유는 많은 데이터가 수신 될 수있는 것보다 길이가 판독 될 때 그 데이터가 separte가 아니기 때문입니다. 가능한 경우 실수를 정정 해 주실 수 있습니까? 이 코드는 클래스 없이는 잘 작동하지만 클래스로 구현 한 후에는 문제가 있습니다. – user3369727

답변

1

client.cpp이 줄을 삭제 작동합니다 :

SOCKET ConnectSocket; 

이전에이 행을 삭제 한 후 코드를 실행 했으므로 정상적으로 작동했습니다.

이 행은 기능 start_listening(), 이 로컬 변수 그림자 부재 변수의 범위 내에서 로컬 변수 ConnectSocket을 정의하는 것을 의미한다. 유효한 파일 설명자를 멤버 변수에 할당하는 것 같지만 멤버 변수 ConnectSocket은 항상 초기화되지 않으므로 send()은 실패합니다.

+0

@ user3369727 .h 파일을 보여 주시겠습니까? – jfly

+0

편집 된 코드를 참조하십시오. – user3369727

+0

문제점을 발견했습니다. 편집을 참조하십시오. – jfly

관련 문제