⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enetsvc.cpp

📁 利用socket编程实现对以太网的模拟!
💻 CPP
字号:
#include <stdio.h>
#include <conio.h>
#include "mytypes.h"
#include "ChnIFace.h"
#include "enet.h"

typedef struct Sta_Reg {
	Sta_Reg	*pNext;
	int		Valid;
	MacAddr	Mac;
	U32		SndCnt;
	U32		RcvCnt;
}Sta_Reg;

int eNetSvc(int port,IP_Addr addr=0x7f000001);
char *CmdReady();
char *AddrStr(IP_Addr addr);
int CmdProc(char *pCmd);
int RecvProc(ChnIFace *pChn);
int eENetInit(ChnIFace *pChn, int port,IP_Addr addr=0x7f000001);
int MsgProc(ChnIFace *pChn, eFrame *pF);
int Forward(ChnIFace *pChn, eFrame *pF, U16 Len);
Sta_Reg *StaMatch(MacAddr mac);
int StaEnQue(Sta_Reg* pS);
Sta_Reg *StaDeQue(MacAddr mac);

Sta_Reg 	*StaQue;
MacAddr		MyMac;   

int main(int argc, char *argv[])
{
	int    id;
	if(argc == 1)
	{
		printf("用法: %s 网络ID号  (1~9,用于标识该网络)\n",argv[0]);
		return 0;
	}
	sscanf(argv[1],"%d",&id);
	if(id < 0 || id>9)
	{
		printf("输入参数错误: %s\n",argv[1]);
		return 0;
	}
	printf("Emulating Ethernet starting, NetID = %s\n", argv[1]);
	
	eNetSvc(3000+id);
	return 0;
}

int eNetSvc(int port,IP_Addr addr)
{
	int More;
	U32 LoopCnt;
	U32 RecvCnt;
	char *pCmd;
	ChnIFace Chn;
	
	if(eENetInit(&Chn,port) != 0)
		return 0;
	
	printf("eNet Service Started at [%s @%d]\n", AddrStr(addr),port); 
	LoopCnt = 0;
	RecvCnt = 0;
	More = 1;
	while(More)
	{
		if(Chn.RecvReady(10))
		{
			RecvProc(&Chn);
			RecvCnt++;
		}
		if ( (pCmd=CmdReady()) )
		{
			More=CmdProc(pCmd);
		}
		LoopCnt++;
	}
	printf("Service terminated\n%ld loops, %ld PDU received.\n",LoopCnt,RecvCnt);
	return 0;
}

int eENetInit(ChnIFace *pChn, int port,IP_Addr addr)
{
	if(pChn->Open(IPPROTO_UDP) !=0)
		return -1;
	if(pChn->Bind(port) != 0)
		return -1;
	MyMac = htons(port);
	StaQue = NULL;
	return 0;
}

char *CmdReady()
{
	static char keys[80];
	static int  k=0;
	int c;
	if(!kbhit())
		return NULL;
	c = getche();
	if (c != '\r')
	{
		keys[k++] = c;
		return NULL;
	}
	keys[k]=0;
	k=0;
	if(strlen(keys))
		return keys;
	return NULL;
}
char *AddrStr(IP_Addr addr)
{
	static char str[64];
	sprintf(str,"%ld.%ld.%ld.%ld",addr>>24,(addr>>16)&0xff,(addr>>8)&0xff,addr&0xff);
	return str;
}
int CmdProc(char *pCmd)
{
	return strcmp(pCmd,"exit");
}
int RecvProc(ChnIFace *pChn)
{
	char Buff[2000];
	int Len;
	MacAddr Mac;
	eFrame	*pF;
	Len = pChn->RecvFrom(Buff,2000,&Mac);
	if(Len != SOCKET_ERROR)
	{
		pF = (eFrame*)Buff;
		if(pF->dMac == MyMac)
			MsgProc(pChn,pF);
		else
			Forward(pChn,pF,Len);
	}
	return 0;
}
int MsgProc(ChnIFace *pChn, eFrame *pF)
{
	Sta_Reg *pS;
	switch(ntohs(pF->Type))
	{
	case CMD_BIND:
		pF->dMac = pChn->GetPeerPort();
		pF->sMac = MyMac;
		pS = StaMatch(pF->dMac);
		if(pS)
			pF->Type = RSP_BINDOK;
		else
		{
			pS = (Sta_Reg*)malloc(sizeof(Sta_Reg));
			if(!pS)
				pF->Type = RSP_BINDNK;
			else
			{
				pS->Mac = pF->dMac;
				pS->Valid = 1;
				pS->SndCnt = 1;
				pS->RcvCnt = 1;
				StaEnQue(pS);
				pF->Type = RSP_BINDOK;
			}
		}
		pChn->SendTo((char*)pF,sizeof(eFrame),pF->dMac);
		break;
	case CMD_UNBIND:
		pS = StaDeQue(pF->sMac);
		if(pS)
			free(pS);
		break;
	}
	return 0;
}
int Forward(ChnIFace *pChn, eFrame *pF, U16 Len)
{
	Sta_Reg *pS;
	
	pS =StaMatch(pF->sMac);
	if(pS)
		pS->SndCnt++;
	if(pF->dMac == MAC_MULTCST)
	{
		pS = StaQue;
		while(pS != NULL)
		{
			if(pS->Mac != pF->sMac && pS->Valid > 0)
			{
				pS->Valid = pChn->SendTo((char*)pF,Len,pS->Mac);
				pS->RcvCnt++;
			}
			pS = pS->pNext;
		}
	}
	else
	{
		pS = StaMatch(pF->dMac);
		if(pS && pS->Valid > 0)
		{
			pS->Valid = pChn->SendTo((char*)pF,Len,pS->Mac);
			pS->RcvCnt++;
		}
	}
	return 0;
}

Sta_Reg *StaMatch(MacAddr mac)
{
	Sta_Reg *pS;
	pS = StaQue;
	while(pS != NULL)
	{
		if(pS->Mac == mac)
			return pS;
		else
			pS = pS->pNext;
	}
	return NULL;
}
int StaEnQue(Sta_Reg* pS)
{
	pS->pNext = StaQue;
	StaQue = pS;
	return 0;
}
Sta_Reg *StaDeQue(MacAddr mac)
{
	Sta_Reg *pS;
	Sta_Reg *p0;
	pS = StaQue;
	if(pS == NULL)
		return NULL;
	if(pS->Mac == mac)
	{
		StaQue = pS->pNext;
		pS->pNext = NULL;
		return pS;
	}
	while(pS->pNext != NULL && pS->pNext->Mac != mac)
		pS = pS->pNext;
	if(pS->pNext != NULL)
	{
		p0 = pS->pNext;
		pS->pNext = p0->pNext;
		p0->pNext = NULL;
		return p0;
	}
	return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -