マルチスレッドソケットプログラミング---プログラムインスタンス(C++実装)


一.プログラム紹介
このプログラムには主に以下の内容が含まれています.
1.マルチスレッドプログラム設計の一般的なフレームワークで、新しいスレッドはネットワークデータの循環受信を担当し、ネットワークデータを受け取るとメインスレッドに処理される.プライマリ・スレッドは、ネットワーク・データのループ処理を担当します.
2.(UDP)ソケットプログラミングの一般的なフレームワークは,このプログラムがUDPソケットのみを用いた実験を容易にするために,パケット損失遅延などのネットワーク問題を考慮せずに,実際のプログラム設計にTCPソケットを採用できる.
3.ソケットを使用して複数の異なる構造体を送信する方法は、異なる構造体に異なるフラグビットを追加することによって、異なる構造体タイプを区別する.
プログラムのデフォルト設定は次のとおりです.
1.各参加者のIPアドレスは127.0.0.1(ループバックアドレス、単機テスト用)である.2.iと番号付けされた参加者のポート番号は10000+iであり、例えば、1と番号付けされた参加者のポート番号は10001である.マルチマシンテストを行うため、各プロセスのIPアドレスは127.0.0.1であるため、異なるポートを使用して異なるプロセスを区別する必要があり、ネットワークデータが正しい参加者に送信されることを保証することができる.3.番号1の参加者は、番号2の参加者にテストデータを送信する.1番の参加者は3つの異なる構造体を2に送信し、参加者2は受信した後、まず構造体のフラグビットを抽出し、その後、どの構造体変数でネットワークデータを受信するかを決定する.正しい構造体に抽出した後、構造体のデータを印刷します.
二.プログラムソース
1.Node.h
#ifndef NORMALNODE
#define NORMALNODE
#include "winsock.h"
#include "windows.h"
#include 
#include 
using namespace std;

const WM_PARTY_MSG=WM_USER+1;

struct m_struct1
{
	int flag;
	char Value1[15];
};

struct m_struct2
{
	int flag;
	char Value1[15];
	char Value2[15];
};

struct m_struct3
{
	int flag;
	char Value1[15];
	char Value2[15];
	char Value3[15];
};

struct ThreadParameter
{
	int Port;
	DWORD MainThreadID;
};

class Node
{
private:
	int ID;//  ID
public:
    Node();
	~Node();
	void StartMyThread();
	int DealMessage(char *MyMessage,int MessageLength);
	static DWORD WINAPI StartAcceptThread(LPVOID lpData);
	int SendStruct();
	int TransmitMessage(int ParticipatorID,char *StructBuffer,int BufferLength);
};

#endif

2.Node.cpp
#include "Node.h"
const MSG_STRUCT1=1;
const MSG_STRUCT2=2;
const MSG_STRUCT3=3;

Node::Node()//    
{
	cout<>ID;
}

Node::~Node()//    
{
	
}

void Node::StartMyThread()//     
{
	DWORD myMainThreadID=::GetCurrentThreadId(); //             ID 
	static ThreadParameter tp;//          
	tp.MainThreadID=myMainThreadID;
	tp.Port=10000+ID;//      
    HANDLE hThread = CreateThread(NULL,0,StartAcceptThread,(LPVOID)&tp,0,NULL);//     
    CloseHandle(hThread);
}

DWORD WINAPI Node::StartAcceptThread(LPVOID lpData)//       ,                 
{
	ThreadParameter tp=*((ThreadParameter *)lpData);
	char RecveBuffer[20][4096];//    ,         ,             ,          ,           ,         ,      
	for(int i=0;i<20;i++)
		memset(RecveBuffer[i],0,4096);
    SOCKET RecveSocket = ::socket(AF_INET, SOCK_DGRAM, 0);//  UDP   
	SOCKADDR_IN sin;
	sin.sin_family = AF_INET;
	sin.sin_addr.S_un.S_addr = INADDR_ANY;	
	sin.sin_port = ::htons(tp.Port);//     
	if(::bind(RecveSocket, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)//        
	{
		cout< 0)
		{
		    //                ,           
			if(PostThreadMessage(tp.MainThreadID,WM_PARTY_MSG,0,(LPARAM)RecveBuffer[recvcount])==0)
			{
				cout<

3.testmian,cpp
#include "Node.h"
int main()
{
	int ret;
	WSADATA wsa;
	//      DLL
	if(WSAStartup(MAKEWORD(2,2),&wsa)!=0)
	{
		cout<

三.スクリーンショットの実行
このプログラムはVC 60プラットフォームの下でコンパイルされた.