Windows下 面向连接的 UDP通信 实验

昨天转了篇Linux下面向连接的UDP通信,想做个实验,看看是否能实现“面向连接”

实验结果表明是:UDP即便使用了connect()函数进行连接,传输失败仍然不会有任何的提示。

实验步骤如下

服务器端:

1. 建立套接字;

2. 绑定套接字;

3. 用recvfrom()、sendto() 函数进行信息的收发;

4. 关闭套接字;

客户端:

1. 建立套接字;

2. 向服务器端发送消息;

3. 接收服务器端回送的消息;

4. 关闭套接字;

注意:使用UDP通信时,客户端并没有显式的调用套接字绑定,但是默认建立好套接字后,如果首先使用sendto()函数,系统会自动实现套接字的绑定。

程序代码如下

共同代码:

初始化套接字类:

头文件

#include <winsock2.h>

class CinitSock  
{
public:
	CinitSock();
	virtual ~CinitSock();
};
实现文件
CinitSock::CinitSock()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
 
	wVersionRequested = MAKEWORD( 2, 2 );
 
	err = WSAStartup( wVersionRequested, &wsaData );
	if ( err ) 
	{
		printf("Ws2_32.lib加载出错");
		return;
	}
 
	if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) 
	{
		printf("Ws2_32.dll加载时版本不匹配,您的机器可能不支持socket2.2版本"); 
		WSACleanup( );
		return; 
	}
}

CinitSock::~CinitSock()
{
	WSACleanup();
}

服务器端:

#include "initSock.h"
#include <stdio.h>

void main()
{
	CinitSock oinitSock;
	SOCKET srvSock=socket(AF_INET, SOCK_DGRAM, 0);

	int addrLen=sizeof(SOCKADDR);

	//设置服务器的套接字
	SOCKADDR_IN srvSockAddr;
	srvSockAddr.sin_family=AF_INET;
	srvSockAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	//srvSockAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	srvSockAddr.sin_port=htons(2030);

	//printf("服务器IP地址:%d", INADDR_ANY);

	if(bind(srvSock, (SOCKADDR *)&srvSockAddr, addrLen))
	{
		printf("绑定出错\n");
		return;
	}
	printf("服务器在127.0.0.1,端口2030上进行监听\n");

	char recvBuf[128]={0};

	//信息源套接字
	SOCKADDR_IN clientSockAddr;

	while(1)
	{
		if(recvfrom(srvSock, recvBuf, 128, 0, (SOCKADDR *)&clientSockAddr, &addrLen)>0)
		{
			printf("接收到数据%s\n", recvBuf);
			char sendBuf[128]={0};
			memcpy(sendBuf, "client, i love u", 128);
			if(sendto(srvSock, sendBuf, 128, 0, (SOCKADDR *)&clientSockAddr, addrLen)>0)
				printf("向客户端发送%s\n", recvBuf);
			else 
			{
				printf("向客户端发送信息失败\n");
				return;
			}
			break;
		}
	}

	closesocket(srvSock);
}
客户端代码:

#include <stdio.h>
#include "initSock.h"

void main()
{
	CinitSock oinitSock;

	SOCKET clientSock=socket(AF_INET, SOCK_DGRAM, 0);
	
	char sendMsg[128]={0};
	memcpy(sendMsg, "server, i love u", strlen("server, i love u"));

	//设置目的套接字地址
	SOCKADDR_IN sockaddrTo;
	sockaddrTo.sin_family=AF_INET;
	sockaddrTo.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	//sockaddrTo.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	sockaddrTo.sin_port=htons(2030);
	int addrLen=sizeof(SOCKADDR);

	
	if(connect(clientSock, (SOCKADDR *)&sockaddrTo, addrLen)==SOCKET_ERROR)
	{
		printf("连接服务器的时候出错\n");
		return;
	}
	

	if(sendto(clientSock, sendMsg, strlen(sendMsg), 0, (SOCKADDR *)&sockaddrTo, addrLen)==SOCKET_ERROR)
	{
		printf("发送信息失败\n");
		return;
	}


	char recvMsg[128];
	while(1)
	{
		if(recvfrom(clientSock, recvMsg, strlen(recvMsg), 0, (SOCKADDR *)&sockaddrTo, &addrLen)>0)
		{
			printf("接收到数据:%s\n", recvMsg);
			break;
		}
	}

	closesocket(clientSock);
}

注意:INADDR_ANY就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。

在服务器端可以使用INADDR_ANY进行ip设置,但在客户端发送消息时,必须指定服务器IP,不能使用INADDR_ANY

实验结果

客户端包括connect()函数和sendto()函数,连接失败或发送失败,根本没有提示。

而且,在windows下也没有linux中的read()和write()函数(连接错误之后系统会给客户端一个连接错误信息),其原因可能是因为linux系统下任何东西都可以看成是文件,在调用connect()函数后,直接用套接字读和写就可以。

你可能感兴趣的:(windows,linux,socket,server,服务器)