Windows socket编程入门

上一篇 / 下一篇  2010-11-18 21:40:54

Socket简单的来说是系统环境下的编程接口,winsock就是windows环境下网络编程的接口(废话来着)。那接口又是什么来着?打个比方,你现在想打电话给你女朋友,这个时候你就需要电信局给你提供的接口----电话机(socket)(这里我先假设你不会使用电话机),然后你会翻阅电信局给你的电话使用说明(msdn):
1.  拿起电话确认电话是好的(创建socket)
2.  申请一个电话号码,和你的电话绑定,电信局帮你接线入网,这样有人打你电话你就知道了。 (绑定socket,listen) 
3.  拨号,等待你女朋友接电话(connect)
4.  好了,你女朋友接电话了,你开始说“我爱你”(send)
5.  她听到了并回答你说“我也爱你”(recv)
6.  接下来你们就开始。。。(send and recv)。
7.  话说完了(close)
上面虽然演示的是打电话的过程,但也表达了winsock的编程模型思想。到这里我们可
以下面的程序了:

很显然,这样的程序是不能编译运行,因为它缺少运行的必要参数。同时有些步骤对我们来说并没有必要,例如对于你女朋友的电话(服务端)来说,她没有必要connect,因为她接了你电话之后你们就已经建立了一个新的通话路线了;同样的,对你来说,你也没有必要listen,因为这次是你打电话,你不需要去监听,因为即使你监听了,你也收不到别人的电话请求,因为你“堵塞”在你女朋友的通话上(以后我们将会逐步解决这个问题)。
这样我们可以把一次完成通讯分成两个部分来完成---服务端与客户端(记住:客户端和服务端并没有明显的区别,主要看服务类型是怎么样的)。这里我们假设服务端只是等待客户端来连接,而客户端则不接受连接只发起连接(你女朋友不会打电话给你,打电话要你主动,而且你打电话她也会接)。这样我们就得到服务端和客户端的伪代码:

在我们开始打电话之前,首先的事情是要要求电信局帮我们把线路架好,因为这是我们进行通话的基础环境。同样的,我们进行socket编程之前也应该初始化socket环境,代码如下:

#include <winsock2.h>  //winsock库,版本2.0
#pragma comment(lib, “ws2_32”)  //加载静态库(如果不明白什么是静态库就自己查查吧),至//于为什么大家可以先不必了解,只要记住这是网络编程必须的就可以了.
WORD wdVersionRequired;
WSADATA wsaData;

wdVersionRequired = MAKEWORD(2, 2);
WSAStartup(wdVersionRequired, &wsaData);



int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
引用

Parameters
wVersionRequested 
[in]我们需要的winsock库版本,(1.1以上即可)
lpWSAData 
[out] 指向一个 WSADATA 数据结构体 用来接受windows socket的详细资料。
(MSDN中in指该参数传入,out指传出)



关于该函数的更多细节,请自行查看msdn

服务端: 


#include <iostream> 
#include <winsock2.h> 
#pragma comment(lib, "ws2_32") 

int main() 

using namespace std; 

WORD wdVersionRequired; 
WSADATA wsaData; 
int err; 

wdVersionRequired = MAKEWORD(2, 2); 
err = WSAStartup(wdVersionRequired, &wsaData); 
//注意函数返回值,0表示正常 
if (0 != err) 

   return 0; 

SOCKET s = socket(AF_INET, SOCK_STREAM, 0); 

if (INVALID_SOCKET == s) 

   cout << "failed socket" << endl; 
   return 0; 

sockaddr_in saServer; 
saServer.sin_family = AF_INET; 
saServer.sin_addr.S_un.S_addr = INADDR_ANY; 
saServer.sin_port = htons(4567); 

err = bind(s, (const sockaddr *)&saServer, sizeof(sockaddr)); 
if (0 != err) 

   cout << "failed bind" << endl; 
   return 0; 

err = listen(s, 10); 
if (0 != err) 

   cout << "failed listen" << endl; 
   return 0; 

char buf[16]; 
sockaddr sa; 
int salen = sizeof(sockaddr); 
SOCKET sClient; 
while(true) 

   sClient = accept(s, &sa, &salen); 
   err = recv(sClient, buf, sizeof(buf), 0); 
   if (err != 0 && err != SOCKET_ERROR) 
   { 
     send(sClient, buf, sizeof(buf), 0); 
     cout << buf << endl; 
   } 

WSACleanup();//释放 

return 1; 



客户端: 


#include <windows.h> 
#pragma comment(lib, "ws2_32") 

#include <iostream> 
using namespace std; 

int main() 

WORD wdVersionRequired; 
WSADATA wsaData; 

wdVersionRequired = MAKEWORD(2, 2); 
WSAStartup(wdVersionRequired, &wsaData); 

SOCKET s = socket(AF_INET, SOCK_STREAM, 0); 
if (SOCKET_ERROR == s) 

   return 0; 

sockaddr_in saServer; 
memset(&saServer, 0, sizeof(saServer)); 
saServer.sin_family = AF_INET; 
saServer.sin_addr.S_un.S_addr = inet_addr("222.200.42.5"); 
saServer.sin_port = htons(4567); 

connect(s, (const sockaddr*)&saServer, sizeof(sockaddr)); 

char buf[16] = "heheheheheheheh"; 
send(s, buf, sizeof(buf), 0); 
recv(s, buf, sizeof(buf), 0); 
cout << buf << endl; 

//WSACleanup(); 
int a; 
cin >> a; 

return 1; 
}


      TAG:

       

      评分:0

      我来说两句

      Open Toolbar