MFC 下的网络编程socket编程

网络编程或者说socket 编程其实很简单,我以前在unix下做过,很容易。

但如何在mfc 或者vc 下编程,我却有点犯难,但我看了

https://blog.csdn.net/mowenliunian/article/details/53341402

之后,我觉得一切又变得很简单了。所以我把他的主要内容复制于此。帮助你我编程应用。

一、基于TCP协议的编程步骤

服务器端:

1. 加载套接字库(WSAStartup)

2. 创建用于监听的套接字(socket),然后将其绑定到本地SOCKADDR(bind),并将其设为监听模式(listen)

3. 等待客户请求的到来:一旦收到客户连接请求,返回一个对应该连接的套接字(accept)

4. 利用返回的套接字与客户端进行通信(recv/send)

5. 通信完毕,关闭套接字(closesocket)并终止套接字库的使用(WSACleanup)

 

[cpp]  view plain  copy
  1. // 加载套接字库  
  2. WSAData wsaData;  
  3. if(0 != WSAStartup(MAKEWORD(1, 1), &wsaData))  
  4. {  
  5.     return;  
  6. }  
  7. if(1 != LOBYTE(wsaData.wVersion) ||  
  8.    1 != HIBYTE(wsaData.wVersion))  
  9. {  
  10.     // 终止对套接字库的使用  
  11.     WSACleanup();  
  12.     return;  
  13. }  
  14.   
  15. // 创建用于监听的套接字  
  16. SOCKET sockListen = socket(AF_INET, SOCK_STREAM, 0);  
  17.   
  18. // 绑定监听套接字到某个本地地址信息结构体  
  19. SOCKADDR_IN addrSrv;  
  20. addrSrv.sin_family = AF_INET;  
  21. addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
  22. addrSrv.sin_port = htons(6000);  
  23. bind(sockListen, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));  
  24.   
  25. // 将监听套接字设为监听模式,准备接收客户请求  
  26. listen(sockListen, 6);  
  27.   
  28. // 处理客户请求  
  29. SOCKADDR_IN addrClient;  
  30. int len = sizeof(SOCKADDR);  
  31. while(1)  
  32. {  
  33.     // 等待客户请求的到来  
  34.     // 每次接收到客户请求后,返回对应本次连接的套接字  
  35.     // 建立连接后,就可以使用返回的套接字与客户端进行通信了  
  36.     SOCKET sockSrv = accept(sockListen, (SOCKADDR *)&addrClient, &len);  
  37.       
  38.     // 发送数据  
  39.     char sendBuf[100];  
  40.     sprintf(sendBuf, "Welcome %s to http://www.communication.org", inet_ntoa(addrClient.sin_addr));  
  41.     send(sockSrv, sendBuf, strlen(sendBuf) + 1, 0);  
  42.   
  43.     // 接收数据  
  44.     char recvBuf[100];  
  45.     recv(sockSrv, recvBuf, sizeof(recvBuf), 0);  
  46.     printf("%s\n", recvBuf);  
  47.   
  48.     // 关闭本次连接的套接字  
  49.     closesocket(sockSrv);  
  50. }  
  51.   
  52. // 终止对套接字库的使用  
  53. WSACleanup();  

客户端:

1. 加载套接字库(WSAStartup)

2. 创建用于通信的套接字(socket)

3. 向服务器发出连接请求(connect)

4. 利用已连接的套接字与服务器进行通信(send/recv)

5. 通信完毕,关闭套接字(closesocket)并终止套接字库的使用(WSACleanup)

 

[cpp]  view plain  copy
  1. // 加载套接字库  
  2. WSADATA wsaData;  
  3. if(0 != WSAStartup(MAKEWORD(1, 1), &wsaData))  
  4. {  
  5.     return;  
  6. }  
  7. if (1 != LOBYTE(wsaData.wVersion) ||  
  8.     1 != HIBYTE(wsaData.wVersion))  
  9. {  
  10.     // 终止对套接字库的使用  
  11.     WSACleanup();  
  12.     return;  
  13. }  
  14.   
  15. // 创建套接字  
  16. SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  
  17.   
  18. // 向服务器发出连接请求  
  19. // 建立连接后,就可以利用请求套接字与服务器进行通信了  
  20. SOCKADDR_IN addrSrv;  
  21. addrSrv.sin_family = AF_INET;  
  22. addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  23. addrSrv.sin_port = htons(6000);  
  24. connect(sockClient, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));  
  25.   
  26. // 接收数据  
  27. char recvBuf[100];  
  28. recv(sockClient, recvBuf, sizeof(recvBuf), 0);  
  29. printf("%s\n", recvBuf);  
  30.   
  31. // 发送数据  
  32. send(sockClient, "This is TcpClient One.", strlen("This is TcpClient One.")+1, 0);  
  33.   
  34. // 关闭套接字,终止套接字库使用  
  35. closesocket(sockClient);  
  36. WSACleanup();  


二、基于UDP协议的编程步骤

服务器端:

1. 加载套接字库(WSAStartup)

2. 创建用于通信的套接字(socket),然后将其绑定到本地SOCKADDR(bind)

3. 利用创建的套接字与客户端进行通信(recvfrom/sendto)

4. 通信完毕,关闭套接字(closesocket)并终止套接字库的使用(WSACleanup)

 

[cpp]  view plain  copy
  1. // 加载套接字库  
  2. WSAData wsaData;  
  3. if(0 != WSAStartup(MAKEWORD(1, 1), &wsaData))  
  4. {  
  5.     return;  
  6. }  
  7. if(1 != LOBYTE(wsaData.wVersion) ||  
  8.    1 != HIBYTE(wsaData.wVersion))  
  9. {  
  10.     // 终止对套接字库的使用  
  11.     WSACleanup();  
  12.     return;  
  13. }  
  14.   
  15.   
  16. // 创建套接字  
  17. SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0);  
  18.   
  19. // 绑定套接字到某个本地地址信息结构体  
  20. SOCKADDR_IN addrSrv;  
  21. addrSrv.sin_family = AF_INET;  
  22. addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
  23. addrSrv.sin_port = htons(6000);  
  24. bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));  
  25.   
  26. // 等待并接收数据  
  27. // 直接利用绑定到本地的套接字进行数据接收  
  28. SOCKADDR_IN addrClient;  
  29. int len = sizeof(SOCKADDR);  
  30. char recvBuf[100];  
  31. recvfrom(sockSrv, recvBuf, sizeof(recvBuf), 0,  
  32.     (SOCKADDR *)&addrClient, &len);  
  33. printf("%s\n", recvBuf);  
  34.   
  35. // 关闭套接字,并终止套接字库的使用  
  36. closesocket(sockSrv);  
  37. WSACleanup();  

客户端:

1. 加载套接字库(WSAStartup)

2. 创建用于通信的套接字(socket)

3. 利用创建的套接字与服务器进行通信(sendto/recvfrom)

4. 通信完毕,关闭套接字(closesocket)并终止套接字库的使用(WSACleanup)

 

[cpp]  view plain  copy
  1. // 加载套接字库  
  2. WSAData wsaData;  
  3. if(0 != WSAStartup(MAKEWORD(1, 1), &wsaData))  
  4. {  
  5.     return;  
  6. }  
  7. if(1 != LOBYTE(wsaData.wVersion) ||  
  8.    1 != HIBYTE(wsaData.wVersion))  
  9. {  
  10.     // 终止对套接字库的使用  
  11.     WSACleanup();  
  12.     return;  
  13. }  
  14.   
  15. // 创建套接字  
  16. SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);  
  17.   
  18. // 直接利用创建的套接字向SOCKADDR指定的服务器发送数据  
  19. SOCKADDR_IN addrSrv;  
  20. addrSrv.sin_family = AF_INET;  
  21. addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  22. addrSrv.sin_port = htons(6000);  
  23. sendto(sockClient, "Hello", strlen("Hello")+1, 0,  
  24.     (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));  
  25.   
  26. // 关闭套接字,并终止套接字库的使用  
  27. closesocket(sockClient);  
  28. WSACleanup();  

三、注意事项

编写基于socket网络应用程序时,需事先做到两件事:

1. 包含头文件:Winsock2.h

2. 添加依赖项:ws2_32.lib

基于TCP协议网络应用程序和基于UDP协议的网络应用程序的区别在于:

1. TCP服务器需要在接收到客户端连接请求后,才能与之通信;而UDP服务器直接利用绑定到本地的套接字等待接收数据,接收到数据后才知道客户端的地址信息

2. TCP客户端需要在与服务器建立链接后,才能与之通信;而UDP客户端直接利用绑定到本地的套接字向服务器发送数据,指定的服务器地址信息可以任意指定,因此不确定能不能被接收

与unix 或者linux 下的区别主要是调用WSAStartup(MAKEWORD(1, 1), &wsaData) 开始, 结束调用WSACleanup()。

一、WSAStartup函数 
int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData ); 
使用Socket的程序在使用Socket之前必须调用WSAStartup函数。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。
二、WSACleanup函数 
int WSACleanup (void); 
应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。

 WSAStartup() - 使用方法

当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。该函数执行成功后返回0 
例:假如一个程序要使用2.1版本的Socket,那么程序代码如下 
wVersionRequested = MAKEWORD( 2, 1 ); 
err = WSAStartup( wVersionRequested, &wsaData );



猜你喜欢

转载自blog.csdn.net/leon_zeng0/article/details/80037072