无法将客户端连接到其他计算机上的服务器
can't connect client to server on different computer
我在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,"%srn", (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] = ' ';
break;
}
}
CString strRecvData;
strRecvData.Format("%srn%s %drn%srnrn", (const char*)CTime::GetCurrentTime().Format("%B %d, %Y %H:%M:%S"), p, portno, rbuf);
m_recvData += strRecvData;
m_bRefershData = true;
strcat(rbuf, "rn");
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();
}
首先,看看客户端得到的错误的描述。你可以这样做:
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。
一个可能的问题是服务器的计算机是通过某种路由器连接到互联网的,所以它不能充当服务器。
相关文章:
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 为什么使用 P/Invoke 调用 dll 时,某些计算机中的 LoadLibrary 失败?
- 当我编译webrtc服务器时,Windows上只支持clang-cl
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 有没有办法知道Tracer是否成功地完全连接到了jaegerclientcpp中的jaeger后端服务器
- 从服务器传输到客户端的消息不会出现
- QTcpSocket在不阻塞GUI的情况下重新连接到服务器
- OpenSSL TLS服务器-使用客户端证书白名单
- 我正在开发服务器,ip作为参数传递不起作用
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- 如何在 Minecraft 服务器上执行命令
- 调试编译的服务器在数据库打开时崩溃
- Boost.asio服务器客户端.连接2台计算机
- 查找服务器计算机中的物理 CPU 插槽数
- 如何在一台本地计算机/主机上对简单的 TCP 客户端/服务器进行单元测试
- 同一网络中两台计算机之间的客户端-服务器应用程序(使用boost::asio)
- 用于 LAN 计算机发现和服务器设置的 UDP 广播
- 在局域网上选择一台计算机作为服务器