2013-03-14 2 views
-1

서버에 메시지 (문자열)를 보내는 mfc의 클라이언트 서버 응용 프로그램이 있고 서버가 메시지를 수신하고 클라이언트가 사용하는 포트의 IP 주소도 표시합니다. 텍스트 상자 다른 컴퓨터에서 클라이언트 exe 파일을 실행 해 보았지만 서버에 연결할 수 없다는 오류 메시지가 나타납니다. 내가 디버그를 실행하고 exe 파일을 릴리스 그래서 문제는 코드에 몇 가지 생각합니다.다른 컴퓨터의 클라이언트와 서버를 연결할 수 없습니다.

클라이언트 코드 :

#include "stdafx.h" 
#include "SocketTestClient.h" 
#include "SocketTestClientDlg.h" 
#include <string> 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


// CAboutDlg dialog used for App About 

class CAboutDlg : public CDialog 
{ 
public: 
    CAboutDlg(); 

// Dialog Data 
    enum { IDD = IDD_ABOUTBOX }; 

    protected: 
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 

// Implementation 
protected: 
    DECLARE_MESSAGE_MAP() 
}; 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
} 

void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
} 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
END_MESSAGE_MAP() 


// CSocketTestClientDlg dialog 




CSocketTestClientDlg::CSocketTestClientDlg(CWnd* pParent /*=NULL*/) 
    : CDialog(CSocketTestClientDlg::IDD, pParent) 
    , m_senddata(_T("")) 
    , m_recvData(_T("")) 
{ 
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 

void CSocketTestClientDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
    DDX_Text(pDX, IDC_EDIT2, m_senddata); 
    DDX_Text(pDX, IDC_EDIT1, m_recvData); 
} 

BEGIN_MESSAGE_MAP(CSocketTestClientDlg, CDialog) 
    ON_WM_SYSCOMMAND() 
    ON_WM_PAINT() 
    ON_WM_QUERYDRAGICON() 
    //}}AFX_MSG_MAP 
    ON_BN_CLICKED(IDOK, &CSocketTestClientDlg::OnBnClickedOk) 
    ON_BN_CLICKED(IDCANCEL, &CSocketTestClientDlg::OnBnClickedCancel) 
END_MESSAGE_MAP() 


// CSocketTestClientDlg message handlers 

BOOL CSocketTestClientDlg::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    // Add "About..." menu item to system menu. 

    // IDM_ABOUTBOX must be in the system command range. 
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
    ASSERT(IDM_ABOUTBOX < 0xF000); 

    CMenu* pSysMenu = GetSystemMenu(FALSE); 
    if (pSysMenu != NULL) 
    { 
     CString strAboutMenu; 
     strAboutMenu.LoadString(IDS_ABOUTBOX); 
     if (!strAboutMenu.IsEmpty()) 
     { 
      pSysMenu->AppendMenu(MF_SEPARATOR); 
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
     } 
    } 

    // Set the icon for this dialog. The framework does this automatically 
    // when the application's main window is not a dialog 
    SetIcon(m_hIcon, TRUE);   // Set big icon 
    SetIcon(m_hIcon, FALSE);  // Set small icon 

    // TODO: Add extra initialization here 

    return TRUE; // return TRUE unless you set the focus to a control 
} 

void CSocketTestClientDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
    if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
    { 
     CAboutDlg dlgAbout; 
     dlgAbout.DoModal(); 
    } 
    else 
    { 
     CDialog::OnSysCommand(nID, lParam); 
    } 
} 

// If you add a minimize button to your dialog, you will need the code below 
// to draw the icon. For MFC applications using the document/view model, 
// this is automatically done for you by the framework. 

void CSocketTestClientDlg::OnPaint() 
{ 
    if (IsIconic()) 
    { 
     CPaintDC dc(this); // device context for painting 

     SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); 

     // Center icon in client rectangle 
     int cxIcon = GetSystemMetrics(SM_CXICON); 
     int cyIcon = GetSystemMetrics(SM_CYICON); 
     CRect rect; 
     GetClientRect(&rect); 
     int x = (rect.Width() - cxIcon + 1)/2; 
     int y = (rect.Height() - cyIcon + 1)/2; 

     // Draw the icon 
     dc.DrawIcon(x, y, m_hIcon); 
    } 
    else 
    { 
     CDialog::OnPaint(); 
    } 
} 

// The system calls this function to obtain the cursor to display while the user drags 
// the minimized window. 
HCURSOR CSocketTestClientDlg::OnQueryDragIcon() 
{ 
    return static_cast<HCURSOR>(m_hIcon); 
} 


void CSocketTestClientDlg::OnBnClickedOk() 
{ 

    SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if(s == -1) 
    { 
     AfxMessageBox("Socket Initialiation Error"); 
    } 
    SOCKADDR_IN serveraddr; 
    struct hostent *hostentry; 


    bool bSent = false; 
    std::string server = "10.13.32.133"; 
    int portno = 1818; 

    hostentry = gethostbyname(server.c_str()); 
    char *pipaddr = inet_ntoa (*(struct in_addr *)*hostentry->h_addr_list); 

    memset(&serveraddr,0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(portno); 
    serveraddr.sin_addr.s_addr = inet_addr(pipaddr); 

    //serv_addr.sa_data = htons(portno); 

    if (connect(s,(SOCKADDR*)&serveraddr,sizeof(SOCKADDR_IN)) < 0) 
    { 
     AfxMessageBox("ERROR connecting to the server"); 
     exit(1); 
    } 

    char sbuf[1024], rbuf[1024]; 

    UpdateData(TRUE); 
    sprintf(sbuf,"%s\r\n", (const char*) m_senddata); 
    if(send(s, sbuf, strlen(sbuf), 0) == strlen(sbuf)) 
    { 
     recv(s, rbuf, 1024, 0); 
     m_recvData = rbuf; 
     UpdateData(FALSE); 
    } 
    ::closesocket(s); 
} 


void CSocketTestClientDlg::OnBnClickedCancel() 
{ 

    OnCancel(); 
} 

서버 코드 :

#include "stdafx.h" 
#include "SocketTestServer.h" 
#include "SocketTestServerDlg.h" 
#include <process.h> 
#include <string> 
#include <sys/types.h> 



#ifdef _DEBUG 
#define new DEBUG_NEW 
#endif 


// CAboutDlg dialog used for App About 

class CAboutDlg : public CDialog 
{ 
public: 
    CAboutDlg(); 

// Dialog Data 
    enum { IDD = IDD_ABOUTBOX }; 

    protected: 
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support 

// Implementation 
protected: 
    DECLARE_MESSAGE_MAP() 
}; 

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) 
{ 
} 

void CAboutDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
} 

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) 
END_MESSAGE_MAP() 


// CSocketTestServerDlg dialog 




CSocketTestServerDlg::CSocketTestServerDlg(CWnd* pParent /*=NULL*/) 
    : CDialog(CSocketTestServerDlg::IDD, pParent) 
    , m_recvData(_T("")) 
{ 
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
} 

void CSocketTestServerDlg::DoDataExchange(CDataExchange* pDX) 
{ 
    CDialog::DoDataExchange(pDX); 
    DDX_Text(pDX, IDC_EDIT1, m_recvData); 
} 

BEGIN_MESSAGE_MAP(CSocketTestServerDlg, CDialog) 
    ON_WM_SYSCOMMAND() 
    ON_WM_PAINT() 
    ON_WM_QUERYDRAGICON() 
    //}}AFX_MSG_MAP 
    ON_BN_CLICKED(IDOK, &CSocketTestServerDlg::OnBnClickedOk) 
    ON_WM_TIMER() 
    ON_BN_CLICKED(IDCANCEL, &CSocketTestServerDlg::OnBnClickedCancel) 
END_MESSAGE_MAP() 


// CSocketTestServerDlg message handlers 

BOOL CSocketTestServerDlg::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    // Add "About..." menu item to system menu. 

    // IDM_ABOUTBOX must be in the system command range. 
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); 
    ASSERT(IDM_ABOUTBOX < 0xF000); 

    CMenu* pSysMenu = GetSystemMenu(FALSE); 
    if (pSysMenu != NULL) 
    { 
     CString strAboutMenu; 
     strAboutMenu.LoadString(IDS_ABOUTBOX); 
     if (!strAboutMenu.IsEmpty()) 
     { 
      pSysMenu->AppendMenu(MF_SEPARATOR); 
      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); 
     } 
    } 

    // Set the icon for this dialog. The framework does this automatically 
    // when the application's main window is not a dialog 
    SetIcon(m_hIcon, TRUE);   // Set big icon 
    SetIcon(m_hIcon, FALSE);  // Set small icon 

    StartServer(); 
    return TRUE; // return TRUE unless you set the focus to a control 
} 

void CSocketTestServerDlg::OnSysCommand(UINT nID, LPARAM lParam) 
{ 
    if ((nID & 0xFFF0) == IDM_ABOUTBOX) 
    { 
     CAboutDlg dlgAbout; 
     dlgAbout.DoModal(); 
    } 
    else 
    { 
     CDialog::OnSysCommand(nID, lParam); 
    } 
} 

// If you add a minimize button to your dialog, you will need the code below 
// to draw the icon. For MFC applications using the document/view model, 
// this is automatically done for you by the framework. 

void CSocketTestServerDlg::OnPaint() 
{ 
    if (IsIconic()) 
    { 
     CPaintDC dc(this); // device context for painting 

     SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); 

     // Center icon in client rectangle 
     int cxIcon = GetSystemMetrics(SM_CXICON); 
     int cyIcon = GetSystemMetrics(SM_CYICON); 
     CRect rect; 
     GetClientRect(&rect); 
     int x = (rect.Width() - cxIcon + 1)/2; 
     int y = (rect.Height() - cyIcon + 1)/2; 

     // Draw the icon 
     dc.DrawIcon(x, y, m_hIcon); 
    } 
    else 
    { 
     CDialog::OnPaint(); 
    } 
} 

// The system calls this function to obtain the cursor to display while the user drags 
// the minimized window. 
HCURSOR CSocketTestServerDlg::OnQueryDragIcon() 
{ 
    return static_cast<HCURSOR>(m_hIcon); 
} 


void CSocketTestServerDlg::StartServer() 
{ 
    SOCKADDR_IN serveraddr; 
    int portno = 1818; 
    memset(&serveraddr,0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(portno); 
    serveraddr.sin_addr.s_addr = INADDR_ANY; 

    m_serversocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if(m_serversocket == -1) 
    { 
     AfxMessageBox("Socket Initialiation Error"); 
    } 

    if(bind(m_serversocket, (SOCKADDR*)&serveraddr,sizeof(SOCKADDR_IN)) < 0) 
    { 
     AfxMessageBox("ERROR binding in the server socket"); 
     exit(1); 
    } 

    if(listen(m_serversocket,0) < 0) 
    { 
     AfxMessageBox("ERROR listening in the server socket"); 
     exit(1); 
    } 

    SetTimer(0x01, 100, NULL); 
} 

static void f(void *p) 
{ 
    CSocketTestServerDlg *pDlg = reinterpret_cast<CSocketTestServerDlg*>(p); 
    pDlg->ProcessClientRequest(); 
} 

void CSocketTestServerDlg::ProcessClientRequest() 
{ 
    SOCKADDR_IN clientaddr; 
    struct hostent *hostentry; 
    int len = sizeof(clientaddr); 
    SOCKET clientsocket = accept(m_serversocket, (sockaddr*)&clientaddr, &len); 

    if(len == -1) 
    { 
     AfxMessageBox("Error accpeting the client socket"); 
    } 
    else 
    { 
     char *p = inet_ntoa(clientaddr.sin_addr); 
     int portno = ntohs(clientaddr.sin_port); 
     // int inet_pton(int af, const char *restrict src, void *restrict dst); 

     char rbuf[1024]; 
     recv(clientsocket, rbuf, 1024, 0); 
     for(int i = 1024; i >= 1; i--) 
     { 
      if(rbuf[i] == '\n' && rbuf[i - 1] == '\r') 
      { 
       rbuf[i-1] = '\0'; 
       break; 
      } 
     } 
     CString strRecvData; 

     strRecvData.Format("%s\r\n%s %d\r\n%s\r\n\r\n", (const char*)CTime::GetCurrentTime().Format("%B %d, %Y %H:%M:%S"), p, portno, rbuf); 
     m_recvData += strRecvData; 
     m_bRefershData = true; 
     strcat(rbuf, "\r\n"); 
     send(clientsocket, rbuf, 1024, 0); 
     closesocket(clientsocket); 
    } 
} 

void CSocketTestServerDlg::OnTimer(UINT_PTR nIDEvent) 
{ 
    int idx = nIDEvent; 

    if(m_bRefershData == true) 
    { 
     m_bRefershData = false; 
     UpdateData(FALSE); 
    } 

    fd_set fds; 
    struct timeval timeout; 
    int result; 
    timeout.tv_sec = 0; 
    timeout.tv_usec = 100; 

    FD_ZERO(&fds); 
    FD_SET(m_serversocket, &fds); 

    int rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout); 
    if (rc==-1) 
    { 
     AfxMessageBox("ERROR selecting in the server socket"); 
     return; 
    } 
    else if(rc > 0) 
    { 
     if (FD_ISSET(m_serversocket, &fds)) 
     { 
      m_bRefershData = false; 
      HANDLE h = (HANDLE) ::_beginthread(f, 0, (void*) this); 
     } 

    }   
    CDialog::OnTimer(nIDEvent); 
} 
void CSocketTestServerDlg::OnBnClickedCancel() 
{ 

    OnCancel(); 
} 

void CSocketTestServerDlg::OnBnClickedOk() 
{ 

    OnOK(); 
} 
+0

많은 코드를 읽을 사람은 아무도 없습니다. 당신은 그것을 좁힐 수 있습니까 ?? –

+0

다른 사람이하는 일은 절대적으로 없으면 아무도 이것을 읽고 디버그하지 않습니다. –

+0

죄송합니다. 나는 모든 것을 보여주고 싶었습니다. 나는 AfxMessageBox ("서버에 연결하는 중 오류") 메시지 주위에 오류가 있다고 생각합니다. 클라이언트 코드에서 - 거의 끝. 그 메시지는 다른 컴퓨터에서 클라이언트를 실행할 때 표시됩니다. – Karen123456

답변

1

가장 먼저는, 클라이언트가 얻을 수있는 오류의 설명을 확인합니다. 다음과 같이 할 수 있습니다.

if (connect(s,(SOCKADDR*)&serveraddr,sizeof(SOCKADDR_IN)) < 0) 
{ 
    CString msg = _T("ERROR connecting to the server: "); 
    msg += _com_error(HRESULT_FROM_WIN32(WSAGetLastError())).ErrorMessage(); 
    AfxMessageBox(msg); 
    exit(1); 
} 

_com_error 클래스에는 comdef.h를 포함시켜야합니다.

하나의 문제는 서버의 컴퓨터가 일종의 라우터를 통해 인터넷에 연결되어있어 서버로 작동 할 수 없다는 것입니다.

+0

감사합니다. 이 라인은 무엇을합니까? msg + = _com_error (HRESULT_FROM_WIN32 (WSAGetLastError())). ErrorMessage(); – Karen123456

+0

그것은 오류 – user1610015

+0

의 문자열 설명으로 Winsock의 마지막 오류 코드를 형식화합니다. 오류를 설명하는 경우 어떻게하면 내 문제를 해결할 수 있습니까? – Karen123456

관련 문제