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("    
"); return; } printf(" 127.0.0.1, 2030
"); char recvBuf[128]={0}; // SOCKADDR_IN clientSockAddr; while(1) { if(recvfrom(srvSock, recvBuf, 128, 0, (SOCKADDR *)&clientSockAddr, &addrLen)>0) { printf(" %s
", recvBuf); char sendBuf[128]={0}; memcpy(sendBuf, "client, i love u", 128); if(sendto(srvSock, sendBuf, 128, 0, (SOCKADDR *)&clientSockAddr, addrLen)>0) printf(" %s
", recvBuf); else { printf("
"); 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("          
"); return; } if(sendto(clientSock, sendMsg, strlen(sendMsg), 0, (SOCKADDR *)&sockaddrTo, addrLen)==SOCKET_ERROR) { printf("
"); return; } char recvMsg[128]; while(1) { if(recvfrom(clientSock, recvMsg, strlen(recvMsg), 0, (SOCKADDR *)&sockaddrTo, &addrLen)>0) { printf(" :%s
", recvMsg); break; } } closesocket(clientSock); }
注意:INADDR(u)ANYとは、住所を0.0.00と指定した住所で、この住所は事実上、住所不定、または「すべての住所」、「任意の住所」を表しています。一般的に、各システムにおいて0値として定義される。
サーバー側ではINADDR_を使用できます。ANYはip設定をしていますが、クライアントがメッセージを送信する場合は、サーバーIPを指定しなければなりません。INADDR__は使用できません。ANY
実験結果
クライアントにはconnect()関数とsendto()関数が含まれていますが、接続に失敗したり、送信に失敗したりして、まったくヒントがありません。
また、windowsにはlinuxのread()とwrite()の関数がありません。この理由は、linuxシステムの下では、ファイルとして認識され、connect()関数を呼び出した後、直接ソケットで読み、書いてもいいからです。