界面变化
添加端口控件 属性: 只能输入数字 添加控件变量:m_server_port 添加ip地址控件 添加控件变量:m_server_address
添加变量好方便获取操控控件
按钮单击事件代码
P表示这是一个指针;C表示是一个常量;T表示在Win32环境中,有一个_T宏,这个宏用来表示你的字符是否使用UNICODE, 如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。 atoi将字符串转为长整数
void CRemoteClientDlg::OnBnClickedBtnTest() { // 把控件的值赋给成员变量 UpdateData(); CClientSocket* pClient = CClientSocket::getInstance(); bool ret = pClient->InitSocket(m_server_address, atoi((LPCTSTR)m_server_port)); if (!ret) { AfxMessageBox("网络初始化失败"); return; } CPacket packet(2000, NULL, 0); pClient->Send(packet); int cmd = pClient->DealCommand(); TRACE("ack:%d\r\n", cmd); pClient->CloseSocket(); }
htonl 函数将u_long从主机转换为 TCP/IP 网络字节顺序
htons 函数将主机u_short转换为 TCP/IP 网络字节顺序 (这是大端) 。
inet_ntoa 函数将 internet 网络地址) (Ipv4 转换为 Internet 标准点十进制格式的 ASCII 字符串。
inet_addr 函数将包含 IPv4 点十进制地址的字符串转换为IN_ADDR结构的正确地址。
InitSocket代码变化
ip地址和端口改为由获取控件上的值了,需要注意获取的是主机字节序的,需要转为网络字节序
// 初始化套接字,true成功,false失败 bool InitSocket(int nIp, int nPort) { if (m_socket_server != INVALID_SOCKET)CloseSocket(); m_socket_server = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addr_server; addr_server.sin_family = AF_INET; // 注意 需要转为网络字节序 addr_server.sin_port = htons(nPort); addr_server.sin_addr.S_un.S_addr = htonl(nIp); // 服务器地址是否成功设置 if (addr_server.sin_addr.S_un.S_addr == NULL) { AfxMessageBox("指定ip地址无效\r\n"); TRACE("连接失败,:%d %s", GetLastError(), GetErrorInfo(GetLastError()).c_str()); return false; } // 发起三次握手,连接成功后服务器就阻塞在recv等待对方发送数据 int ret = connect(m_socket_server, (sockaddr*)&addr_server, sizeof(SOCKADDR_IN)); if (ret == -1) { AfxMessageBox("连接失败\r\n"); TRACE("连接失败,:%d %s", GetLastError(), GetErrorInfo(GetLastError()).c_str()); return false; } return true; }
dialog 初始化 初始化ip和端口的值
// 把控件的值赋给成员变量 UpdateData(true); // 把变量的值赋给控件 UpdateData(false); // 端口和IP控件初始化 UpdateData(); m_server_address = 0x7F000001; m_server_port = _T("60000"); UpdateData(false);