windows下 socket编程

 一、基于TCP的socket编程

服务器端程序:

1)创建套接字(socket)。

此系统调用的实际效果是,请求操作系统把网络通信所需要的一些系统资源(存储器空间、CPU时间、网络宽带等)分配给该应用进程。

2)将套接字绑定到一个本地地址和端口上(bind)。

3)将套接字设为监听模式,准备接收客户请求(listen)。

4)等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

5)用返回的套接字和客户端进行通信(send/recv)。

6)返回,等待另一客户请求。

7)关闭套接字(closesocket)。

此系统调用,通知操作系统回收与该套接字描述符相关的所有资源。

客户端程序:

1)创建套接字(socket)。

2)向服务器发出连接请求(connect)。

3)和服务器端进行通信(send/recv)。

4)关闭套接字(closesocket)。

二、基于UDP的socket编程

服务器端(接收端)程序:

1)创建套接字(socket)。

2)将套接字绑定到一个本地地址和端口上(bind)。

3)等待接收数据(recvfrom)。

4)关闭套接字(closesocket)。

客户端(发送端)程序:

1)创建套接字(socket)。

2)向服务器发送数据(sendto)。

3)关闭套接字(closesocket)。

 三、相关函数   

1)int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData); //启动进程使用ws2.dll

wVersionRequested参数:用于指定准备加载的Winsock库的版本。高位字节指定所需要的Winsock库的副版本,而低位字节则是主版本。可用MAKEWORD(x, y);(其中,x是高位字节,y是低位字节)方便地获得wVersionRequested的正确值。

 lpWSAData参数:指向WSADATA结构的指针,WSAStartup用其加载的库版本有关的信息填在这个结构中。

2)SOCKET socket(int af, int type, int protocol); //创建与特定服务提供者绑定的套接字

af参数:指定地址族,对于TCP/IP协议的套接字,它只能是AF_INET(也可写成PF_INET)。

type参数:指定Socket类型,对于1.1版本的Socket,它只支持两种类型的套接字,SOCK_STREAM指定产生流式套接字,SOCK_DGRAM产生数据报套接字。

protocol参数:与特定的地址家族相关的协议,如果指定为0,那么它就会根据地址格式和套接字类别,自动为你选择一个合适的协议。这是推荐使用的一种选择协议的方法。

3)int bind(SOCKET s, const struct sockaddr FAR *name, int namelen); //将套接字和本地地址联系起来

s参数:指定要绑定的套接字。

name参数:指定了该套接字的本地地址信息。

namelen参数:指定name所指向的sockaddr结构的长度。

四、实例

(1)基于TCP的Socket编程

服务器端,创建一个Win32的控制台应用程序,新建一个cpp文件,取名为Server.cpp,其代码如下:

[cpp]  view plain copy
  1. #pragma comment(lib,"Ws2_32.lib")   
  2.   
  3. #include <Winsock2.h>  
  4. #include <iostream>  
  5. using namespace std;  
  6. #include <stdio.h>  
  7. #include <string.h>  
  8.   
  9. int main()  
  10. {  
  11.     //********获取应用程序所需的Winsock DLL版本信息  
  12.     WORD wVersionRequested;  
  13.     wVersionRequested = MAKEWORD(1, 1); //设置高字节为1,低字节为1的WORD类型,表示所需Windows Sockets的版本号为1.1  
  14.     WSADATA wsaData; //用来存储获取的Windows Sockets的信息  
  15.     int err = WSAStartup(wVersionRequested, &wsaData); //初始化此进程的Winsock DLL的使用  
  16.       
  17.     //初始化失败,直接返回  
  18.     if (err != 0)  
  19.     {  
  20.         return 1;   
  21.     }  
  22.   
  23.     //告诉使用者,找不到可用的Winsock DLL  
  24.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  25.     {  
  26.         WSACleanup();  
  27.         return 1;  
  28.     }  
  29.   
  30.     //*********创建套接字  
  31.     SOCKET sockServer = socket(AF_INET, SOCK_STREAM, 0);  
  32.   
  33.     //*********将套接字绑定到一个本地地址和端口上  
  34.     sockaddr_in addrServer; //存储sock地址信息  
  35.     addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //IP地址为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据  
  36.     addrServer.sin_family = AF_INET; //地址簇  
  37.     addrServer.sin_port = htons(6000);  
  38.   
  39.     bind(sockServer, (sockaddr *)&addrServer, sizeof(sockaddr));  
  40.   
  41.     //*********将套接字设为监听模式,准备接收客户请求  
  42.     listen(sockServer, 5); //监听的套接字最大数为5  
  43.   
  44.     //*********等待客户请求到来  
  45.     sockaddr_in addrClient; //存储sock所连接的客户端的地址信息  
  46.     int addrlen = sizeof(sockaddr);  
  47.   
  48.     while (1)   
  49.     {  
  50.         //当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字  
  51.         SOCKET sockConnect = accept(sockServer, (sockaddr *)&addrClient, &addrlen);   
  52.   
  53.         //*********用返回的套接字和客户端进行通信  
  54.         char pBuffer[100];  
  55.         memset(pBuffer, 0, 100);  
  56.         strcat(pBuffer, "Welcome ");  
  57.         strcat(pBuffer, inet_ntoa(addrClient.sin_addr));  
  58.         strcat(pBuffer, " to http://www.sunxin.org!");  
  59.         send(sockConnect, pBuffer, (strlen(pBuffer) + 1) * sizeof(char), 0); //给客户端发送消息  
  60.   
  61.         char recvBuf[100];  
  62.         memset(recvBuf, 0, 100);  
  63.         recv(sockConnect, recvBuf, 100, 0); //接收客户端发来的消息  
  64.   
  65.         //*********关闭socket连接  
  66.         closesocket(sockConnect);   
  67.   
  68.         cout<<recvBuf<<endl;  
  69.     }  
  70.   
  71.     return 0;  
  72. }  

客户端,创建一个Win32的控制台应用程序,新建一个cpp文件,取名为Client.cpp,其代码如下:

[cpp]  view plain copy
  1. #pragma comment(lib,"Ws2_32.lib")   
  2.   
  3. #include <Winsock2.h>  
  4. #include <iostream>  
  5. using namespace std;  
  6. #include <stdio.h>  
  7. #include <string.h>  
  8.   
  9. int main()  
  10. {  
  11.     //********获取应用程序所需的Winsock DLL版本信息  
  12.     WORD wVersionRequested;  
  13.     wVersionRequested = MAKEWORD(1, 1); //设置高字节为1,低字节为1的WORD类型,表示所需Windows Sockets的版本号为1.1  
  14.     WSADATA wsaData; //用来存储获取的Windows Sockets的信息  
  15.     int err = WSAStartup(wVersionRequested, &wsaData); //初始化此进程的Winsock DLL的使用  
  16.       
  17.     //初始化失败,直接返回  
  18.     if (err != 0)  
  19.     {  
  20.         return 1;   
  21.     }  
  22.   
  23.     //告诉使用者,找不到可用的Winsock DLL  
  24.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  25.     {  
  26.         WSACleanup();  
  27.         return 1;  
  28.     }  
  29.   
  30.     //*********创建套接字  
  31.     SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);  
  32.   
  33.     //*********向服务器发出连接请求  
  34.     sockaddr_in addrServer; //存储服务器端的sock地址信息  
  35.     addrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //服务器IP地址,此处服务器为本机  
  36.     addrServer.sin_family = AF_INET; //地址簇  
  37.     addrServer.sin_port = htons(6000);  
  38.   
  39.     connect(sockClient, (sockaddr *)&addrServer, sizeof(sockaddr));  
  40.   
  41.     //*********和服务器端进行通信  
  42.     char *pBuffer = "This is liuxijiao.";  
  43.     send(sockClient, pBuffer, (strlen(pBuffer) + 1) * sizeof(char), 0); //给服务器发送消息  
  44.   
  45.     char recvBuf[100];  
  46.     memset(recvBuf, 0, 100);  
  47.     recv(sockClient, recvBuf, 100, 0); //接收服务器发来的消息  
  48.   
  49.     //*********关闭socket连接  
  50.     closesocket(sockClient);   
  51.     WSACleanup();  
  52.   
  53.     cout<<recvBuf<<endl;  
  54.     system("PAUSE");  
  55.   
  56.     return 0;  
  57. }  

首先运行服务器端的程序,然后再运行客户端的程序。

在服务器端收到客户端发送来的消息:

在客户端收到服务器端发送来的消息:

(2)基于UDP的Socket编程

服务器端,创建一个Win32的控制台应用程序,新建一个cpp文件,取名为Server.cpp,其代码如下:

[cpp]  view plain copy
  1. #pragma comment(lib, "Ws2_32.lib")  
  2.   
  3. #include <Winsock2.h>  
  4. #include <iostream>  
  5. using namespace std;  
  6. #include <stdio.h>  
  7. #include <string.h>  
  8.   
  9. int main()  
  10. {  
  11.     //********获取应用程序所需的Winsock DLL版本信息  
  12.     WORD wVersionRequested;  
  13.     wVersionRequested = MAKEWORD(1, 1); //设置高字节为1,低字节为1的WORD类型,表示所需Windows Sockets的版本号为1.1  
  14.     WSADATA wsaData; //用来存储获取的Windows Sockets的信息  
  15.     int err = WSAStartup(wVersionRequested, &wsaData); //初始化此进程的Winsock DLL的使用  
  16.   
  17.     //初始化失败,直接返回  
  18.     if (err != 0)  
  19.     {  
  20.         return 1;  
  21.     }  
  22.   
  23.     //告诉使用者,找不到可用的Winsock DLL  
  24.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  25.     {  
  26.         WSACleanup();  
  27.         return 1;  
  28.     }  
  29.   
  30.     //***********创建套接字  
  31.     SOCKET sockServer = socket(AF_INET, SOCK_DGRAM, 0);  
  32.   
  33.     //***********将套接字绑定到一个本地地址和端口上  
  34.     sockaddr_in addrServer;  
  35.     addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
  36.     addrServer.sin_family = AF_INET;  
  37.     addrServer.sin_port = htons(6000);  
  38.     bind(sockServer, (sockaddr *)&addrServer, sizeof(sockaddr));  
  39.   
  40.     //***********等待接收数据  
  41.     char pBuffer[100];  
  42.     memset(pBuffer, 0, 100);  
  43.     sockaddr_in addrClient;  
  44.     int len = sizeof(sockaddr_in);  
  45.     recvfrom(sockServer, pBuffer, 100, 0, (sockaddr *)&addrClient, &len); //接受客户端发来的消息  
  46.   
  47.     //***********关闭套接字  
  48.     closesocket(sockServer);  
  49.   
  50.     cout<<pBuffer<<endl;  
  51.     system("PAUSE");  
  52.   
  53.     return 0;  
  54. }  

客户端,创建一个Win32的控制台应用程序,新建一个cpp文件,取名为Client.cpp,其代码如下:

[cpp]  view plain copy
  1. #pragma comment(lib, "Ws2_32.lib")  
  2.   
  3. #include <Winsock2.h>  
  4. #include <iostream>  
  5. using namespace std;  
  6. #include <stdio.h>  
  7. #include <string.h>  
  8.   
  9. int main()  
  10. {  
  11.     //********获取应用程序所需的Winsock DLL版本信息  
  12.     WORD wVersionRequested;  
  13.     wVersionRequested = MAKEWORD(1, 1); //设置高字节为1,低字节为1的WORD类型,表示所需Windows Sockets的版本号为1.1  
  14.     WSADATA wsaData; //用来存储获取的Windows Sockets的信息  
  15.     int err = WSAStartup(wVersionRequested, &wsaData); //初始化此进程的Winsock DLL的使用  
  16.   
  17.     //初始化失败,直接返回  
  18.     if (err != 0)  
  19.     {  
  20.         return 1;  
  21.     }  
  22.   
  23.     //告诉使用者,找不到可用的Winsock DLL  
  24.     if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)  
  25.     {  
  26.         WSACleanup();  
  27.         return 1;  
  28.     }  
  29.   
  30.     //***********创建套接字  
  31.     SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);  
  32.   
  33.     //***********向服务器发送数据  
  34.     char *pBuffer = "Hello, server!";  
  35.     sockaddr_in addServer;  
  36.     addServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");  
  37.     addServer.sin_family = AF_INET;  
  38.     addServer.sin_port = htons(6000);  
  39.     sendto(sockClient, pBuffer, (strlen(pBuffer) + 1) * sizeof(char), 0, (sockaddr *)&addServer, sizeof(sockaddr_in));  
  40.   
  41.     //***********关闭套接字  
  42.     closesocket(sockClient);  
  43.   
  44.     return 0;  
  45. }  
  46. 首先运行服务器端的程序,然后再运行客户端的程序。可看见在服务器端收到客户端发送来的消息:



猜你喜欢

转载自blog.csdn.net/baideweidao/article/details/15808881