参考《Visual C++网络高级编程》(陈坚&陈伟)人民邮电出版社。2.2节,写了客户端程序和服务器程序,winsock程序具体参考书中内容。代码具体见 http://download.youkuaiyun.com/source/3075587。之所称这个程序为简单示例,是应为这种使用套接字的方法不够完善,程序实际跑起来是有点卡的,但足够说明套接字编程的思路和过程了.....
服务器: 创建套接字->将本地地址绑定到套接字->将套接字置入监听模式->使套接字做好接受客户机的准备->阻塞,等待网络数据
//---------------创建套接字--------------------- if(m_hSocket != NULL) {//防止第二次点击按钮时多次创建套接字 closesocket(m_hSocket); m_hSocket = NULL; } if(m_hSocket == NULL) {//创建套接字 m_hSocket = socket(AF_INET, SOCK_STREAM, 0); ASSERT(m_hSocket != NULL); } //--------------将本地地址绑定套接字------------- SOCKADDR_IN addr; addr.sin_family = AF_INET;//表示套接字在internet域中进行通信 addr.sin_addr.S_un.S_addr = INADDR_ANY;//允许套接字对任意IP进行通信 UpdateData(TRUE); addr.sin_port = htons(m_nPort);//得到输入端口号 int ret = 0; int err = 0; ret = bind(m_hSocket, (LPSOCKADDR)&addr, sizeof(addr)); if(ret==SOCKET_ERROR) { TRACE("Bind Error: %d/n", (err=WSAGetLastError())); return; } //--------------将套接字置入监听模式------------- ret = listen(m_hSocket, 3);//允许3个客户机同时发送连接请求 if(ret==SOCKET_ERROR) { TRACE("Bind Error: %d/n", (err=WSAGetLastError())); return; } //--------------使套接字做好接收客户机的准备----- SOCKET s = accept(m_hSocket, NULL, NULL); if(ret==SOCKET_ERROR) { TRACE("Bind Error: %d/n", (err=WSAGetLastError())); return; }
客户机:创建套接字->与服务器链接->向服务器发送数据
//---------------创建套接字--------------------- if(m_hSocket != NULL) {//防止第二次点击按钮时多次创建套接字 closesocket(m_hSocket); m_hSocket = NULL; } if(m_hSocket == NULL) {//创建套接字 m_hSocket = socket(AF_INET, SOCK_STREAM, 0); ASSERT(m_hSocket != NULL); } //--------------创建连接------------- SOCKADDR_IN addr; addr.sin_family = AF_INET;//表示套接字在internet域中进行通信 UpdateData(TRUE); addr.sin_addr.S_un.S_addr = inet_addr(m_strIpAddr.GetBuffer(0));//从文本框控件中读取IP地址 addr.sin_port = htons(m_nPort);//得到输入端口号 int ret = 0; int err = 0; ret = connect(m_hSocket, (LPSOCKADDR)&addr, sizeof(addr)); if(ret==SOCKET_ERROR) { TRACE("Connect Error: %d /n", (err = WSAGetLastError())); if(err == 10061) AfxMessageBox(_T("请确认服务器确实已经打开并工作在同样的端口!")); return ; } //------------将输入数据发送---------- CString str; str += m_strData.GetLength(); str += m_strData; char *buf = str.GetBuffer(0); ret = send(m_hSocket, buf, str.GetLength(), 0); if(ret != str.GetLength()) { TRACE("Send data error: %d/n", WSAGetLastError()); return; }
套接字编程有一种独特的风格,使用一个函数,处理一下异常......看上去还比较有调理。
需要说明的是,这个程序在实验室内部(同一个子网)下是可以正常通信的,但我把服务器程序放在远程(外省),就不能通信了,原因现在还不知道,以后有时间在研究吧....
指定IP
下面这种方法在客户机的connet()和服务器的bind()下都可以使用
SOCKADDR_IN addr; addr.sin_family = AF_INET;//表示套接字在internet域中进行通信 UpdateData(TRUE); addr.sin_addr.S_un.S_addr = inet_addr(m_strIpAddr.GetBuffer(0));//从文本框控件中读取IP地址 addr.sin_port = htons(m_nPort);//得到输入端口号 int ret = 0; int err = 0; ret = connect(m_hSocket, (LPSOCKADDR)&addr, sizeof(addr));
优快云下载处上传代码有一段滞后时间,上传后不能立即查看,而这个程序是几天前就写了的,为了附上链接代码,现在才写文章记录。