📄 simulate.c
字号:
/* ###########################################################################
### VIA-TELECOM CHINA HANGZHOU
### Copyright (c) VIA-TELECOM Corporation 2003-2005
### All Rights Reserved.
### -------------------------------------------------------------------------
### Project: Flash Storage Manager
###
### Module: Simulator.c - FSM Storage Manager Simulator
###
### Archive:
### Revision: Draft
### Date: 2003/07/02 10:30:00
### Author: Embeded SoftWare
### NoKeywords
########################################################################### */
/****************************************
*
* Version Modification Release
*
****************************************/
#include "fsmdefs.h"
#include "FsmVfs.h"
#include "Ostype.h"
#include "FsmFs.h"
#include <winsock.h>
#include <direct.h>
#include <windef.h>
#include <memory.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <io.h>
#include <time.h>
/******************************************
*
* Import or Global variable Declarations
*
******************************************/
#define WIN95
typedef uint32 FS_HANDLE;
#define MAX_FILE_OPEN 16
#define MAX_MOUNT_DEVICE 3
#define SIM_FD_MIN 0
#define MAX_THREAD_NUM 0x10
#define SIM_MAX_FILE 0x40
enum
{
WIN = 0,
FSM = 1
}FileType;
#define VOLNAME "testv/"
#define THREADTYPE_SOCKET 1
typedef struct NETSERVERCTL_t
{
int FatherSocket; // 监听者SOCKET号
int PortNumber; // 端口号
int Type; // 一旦产生线程,其类型
int ChildSocket[8]; // 产生的子 SOCKET 号
int Connector[8]; // 连接者的 IP 地址
int Head; // 用于向 ChildSocket 放
int Tail; // 用于从 ChildSocket 取
int ThreadHandle; // 线程句柄
}NETSERVER;
typedef struct
{
uint32 ThreadID;
int SocketID;
int ThreadType;
uint8 IsUsed;
int Rfu;
}ThreadCtrlT;
typedef struct SYSTEM_DATA_t
{
int QuitMode;
// SEM_ID SysSemId;
int WriteTaskWorkFlag;
NETSERVER NetServer[2];
ThreadCtrlT TreadCtrl_t[MAX_THREAD_NUM];
}SystemDataT;
typedef /*PACKED*/ struct
{
uint8 FileType;
uint32 LowerFdIdx;
uint8 IsUsed;
} SimFDT;
char tab[]="0123456789ABCDEF";
//-------------------------------------------------------------------------
// 定义功能键的扫描码
//-------------------------------------------------------------------------
#define _KEY_F1 0x3b
#define _KEY_F2 0x3c
#define _KEY_F3 0x3d
#define _KEY_F4 0x3e
#define _KEY_F5 0x3f
#define _KEY_F6 0x40
#define _KEY_F7 0x41
#define _KEY_F8 0x42
#define _KEY_F9 0x43
#define _KEY_F10 0x44
#define _KEY_F11 0x85
#define _KEY_F12 0x86
#define _KEY_DEL 0x53
#define _KEY_PGUP 0x49
#define _KEY_PGDN 0x51
#define _KEY_HOME 0x47
#define _KEY_END 0x4f
#define _KEY_INS 0x52
#define _KEY_ARROW_LEFT 0x4b
#define _KEY_ARROW_RIGHT 0x4d
#define _KEY_ARROW_UP 0x48
#define _KEY_ARROW_DOWN 0x50
//-------------------------------------------------------------------------
// 定义控制键的ASCII码
//-------------------------------------------------------------------------
#define _KEY_TAB 0x09
#define _KEY_BACK 0x08
#define _KEY_CR 0x0d
#define _KEY_LF 0x0a
#define _KEY_ESC 0x1b
SystemDataT system_data;
extern HMSEM VOLUME_Lock;
extern FsmVolumeT Volume_Array[VOLUME_NUMBER];
extern FsmVfsFileDescriptorT VFD_Array[FSM_FD_MAX];
extern uint32 FsmGetMatchedVolume (char ** path);
extern uint32 DfsReclaimProcess(FsmDevObjHdrT * DevObjP);
SimFDT SimFd_t[SIM_MAX_FILE];
int StartWorking();
int FsmPrintf(const char * format, ...);
int NetClientConnectScan();
/*
将内存块分为固定长度(BlockSize)的若干(BlockNum)块;
将每个Block分为若干个sectors(根据SectorSize);
将BlockInfo和SectorInfo写入;
设计一种退出方式,模仿掉电;
*/
/*------------------------------------------------------------------*/
/* 对TCPIP协议进行初始化*/
/* 返回 0 成功*/
/* 否则失败*/
/*------------------------------------------------------------------*/
int TCPIP_init()
{
#ifdef WIN95
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return 1;
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
return 1;
}
return 0;
#endif
}
int CreatePhysicalThread(unsigned long (__stdcall * f)(void * x),int * y,int * ThreadID)
{
#ifdef WIN95
return (int)CreateThread(0,0x10000,f,y,CREATE_SUSPENDED,ThreadID);
#endif
}
/*------------------------------------------------------------------*/
/* 打开一个 SOCKET*/
/* 入口: kind 1 UDP*/
/* 2 TCP*/
/* 返回: 若>0,则是socket句柄*/
/* 否则打开失败*/
/*------------------------------------------------------------------*/
int OpenSocket(int kind)
{
#ifdef WIN95
return socket(AF_INET,(kind == 1) ? SOCK_DGRAM : SOCK_STREAM,0);
#endif
}
/*------------------------------------------------------------------*/
/* 把某个 socket 置成非阻塞方式*/
/* 入口: id SOCKET 句柄*/
/* 返回: 0 成功*/
/* 否则失败*/
/*------------------------------------------------------------------*/
int SetSocketNonBlocked(int id)
{
#ifdef WIN95
static long flag = 1;
return ioctlsocket(id,FIONBIO,&flag);
#endif
}
/*------------------------------------------------------------------*/
/* 把一个ASCIIZ形式的 IP 地址变成内部码*/
/* 入口: s IP的ASCIIZ码*/
/* 出口: IP地址的内部码*/
/*------------------------------------------------------------------*/
int GetIPAddress(char * s)
{
#ifdef WIN95
return inet_addr(s);
#endif
}
/*------------------------------------------------------------------*/
/* 把一个SOCKET与一个本地端口联系起来*/
/* 入口: id SOCKET句柄*/
/* port 本地端口号*/
/* 出口: 0 成功 否则失败*/
/*------------------------------------------------------------------*/
int BindSocket(int id,int port)
{
#ifdef WIN95
struct sockaddr_in s;
memset(&s,0,sizeof(s));
s.sin_family = AF_INET;
s.sin_port = htons((short)port);
s.sin_addr.s_addr = INADDR_ANY;
return bind(id,(struct sockaddr *)&s,sizeof(s));
#endif
}
/*------------------------------------------------------------------*/
/* 启动一个SOCKET的LISTEN动作*/
/* 入口: id SOCKET句柄*/
/* 出口: 0 成功*/
/* 否则 失败*/
/*------------------------------------------------------------------*/
int ListenSocket(int id)
{
#ifdef WIN95
return listen(id,1);
#endif
}
/*------------------------------------------------------------------*/
/* 接纳一个客户端来的呼叫*/
/* 入口: id LISTEN的SOCKET句柄*/
/* 出口: 若>0 新SOCKET句柄,该句柄可与客户端通信*/
/* 若<=0 失败*/
/*------------------------------------------------------------------*/
int AcceptSocket(int id,int connector[])
{
#ifdef WIN95
struct sockaddr_in s;
int name_length,z;
memset(&s,0,sizeof(s));
name_length = sizeof(s);
z = accept(id,(struct sockaddr *)&s,&name_length);
if (connector)
connector[0] = *(int *)&s.sin_addr;
return z;
#endif
}
/*------------------------------------------------------------------*/
/* 客户端呼叫服务器*/
/* 入口: id SOCKET句柄*/
/* ip 服务器IP地址内部码*/
/* port 服务器端口号*/
/* 出口: 0 成功*/
/* 否则 失败*/
/*------------------------------------------------------------------*/
int ConnectSocket(int id,int ip,int port)
{
#ifdef WIN95
struct sockaddr_in s;
memset(&s,0,sizeof(s));
s.sin_family = AF_INET;
s.sin_port = htons((short)port);
s.sin_addr.s_addr = ip;
return connect(id,(struct sockaddr *)&s,sizeof(s));
#endif
}
/*------------------------------------------------------------------*/
/* 在一个UDP端口上读一个报文*/
/* 入口: id SOKCET句柄*/
/* buf[] 缓冲区地址*/
/* len 缓冲区长度*/
/* 出口: >0 成功,读出的字节数*/
/* 否则 失败*/
/*------------------------------------------------------------------*/
int ReadFrame(int id,char buf[],int len)
{
#ifdef WIN95
struct sockaddr_in s;
int i;
i = sizeof(s);
return recvfrom(id,buf,len,0,(struct sockaddr *)&s,&i);
#endif
}
/*------------------------------------------------------------------*/
/* 在一个UDP端口上发送一个报文*/
/* 入口: id SOKCET句柄*/
/* buf[] 缓冲区地址*/
/* len 缓冲区长度*/
/* 出口: >0 成功,读出的字节数*/
/* 否则 失败*/
/*------------------------------------------------------------------*/
int SendFrame(int id,char buf[],int len,int IPAddress,int PortNumber)
{
#ifdef WIN95
struct sockaddr_in s;
memset(&s,0,sizeof(s));
s.sin_family = AF_INET;
s.sin_port = htons((short)PortNumber);
s.sin_addr.s_addr = IPAddress;
return sendto(id,buf,len,0,(struct sockaddr *)&s, sizeof(s));
#endif
}
/*------------------------------------------------------------------*/
/* 在一个TCP端口上一个字节流*/
/* 入口: id SOCKET句柄*/
/* buf[] 缓冲区地址*/
/* len 缓冲区长度*/
/* 出口: >0 成功,读出的字节数*/
/* =0 失败,对方已关闭端口*/
/* <0 失败,对方已异常终止或没有数据可读*/
/*------------------------------------------------------------------*/
int subReadStream(int id,char buf[],int len)
{
#ifdef WIN95
return recv(id,buf,len,0);
#endif
}
/*------------------------------------------------------------------*/
/* 取出错码*/
/* 入口: 无*/
/* 返回: 1 表示没有数据可读或TCP发送缓冲区满*/
/* 2 表示该通道已经关闭或异常终止*/
/*------------------------------------------------------------------*/
int GetErrorCode()
{
#ifdef WIN95
return (WSAGetLastError() == WSAEWOULDBLOCK) ? 1 : 2;
#endif
}
/*------------------------------------------------------------------*/
/* 在一个TCP端口上读一个字节流 */
/* 入口: id SOCKET句柄 */
/* buf[] 缓冲区地址 */
/* len 缓冲区长度 */
/* 出口: >0 成功,读出的字节数 */
/* =0 失败,对方已关闭端口 */
/* <0 失败,没有数据可读 */
/*------------------------------------------------------------------*/
int ReadStream(int id,char buf[],int len)
{
int a,x;
#ifdef WIN95
a = recv(id,buf,len,0);
if (a >= 0)
{
x = a;
}
else
{
x= (GetErrorCode() == 1) ? -1 : 0;
}
return x;
#endif
}
/*------------------------------------------------------------------*/
/* 在一个TCP端口上发送一个字节流*/
/* 入口: id SOCKET句柄*/
/* buf[] 缓冲区地址*/
/* len 缓冲区长度*/
/* 出口: >=0 成功,发出的字节数*/
/* <0 失败,TCP缓冲区满或对方已异常终止*/
/*------------------------------------------------------------------*/
int subSendStream(int id,char buf[],int len)
{
#ifdef WIN95
return send(id,buf,len,0);
#endif
}
/*------------------------------------------------------------------*/
/* 在一个TCP端口上发送一个字节流*/
/* 入口: id SOCKET句柄*/
/* buf[] 缓冲区地址*/
/* len 缓冲区长度*/
/* 出口: >0 成功,发出的字节数*/
/* ==0 失败,SOCKET关闭或异常
/* <0 失败,TCP缓冲区满或没有数据可发*/
/*------------------------------------------------------------------*/
int SendStream(int id,char buf[],int len)
{
#ifdef WIN95
int a,x;
a = send(id,buf,len,0);
if(a > 0)
{
x = a;
}
else if(a == 0)
{
x = -1;
}
else
{
x = (GetErrorCode() == 1) ? -1 : 0;
}
return x;
#endif
}
/*------------------------------------------------------------------*/
/* 关闭SOCKET*/
/* 入口: id SOCKET句柄*/
/* 出口: 0 成功*/
/* 否则 失败*/
/*------------------------------------------------------------------*/
int CloseSocket(int id)
{
#ifdef WIN95
return closesocket(id);
#endif
}
int TerminatePhysicalThread(int id)
{
#ifdef WIN95
TerminateThread((HANDLE)id,0);
return CloseHandle((HANDLE)id);
#endif
}
static unsigned long __stdcall PhysicalThread(void *y)
{
uint32 ThreadID;
int i;
int socket_id;
ThreadID = GetCurrentThreadId();
for(i = 0; i < MAX_THREAD_NUM; i++)
{
if(ThreadID == system_data.TreadCtrl_t[i].ThreadID)
{
break;
}
}
if(i == MAX_THREAD_NUM)
{
return 0;
}
socket_id = system_data.TreadCtrl_t[i].SocketID;
SetSocketNonBlocked(socket_id); // BIND成功后,把SOCKET置成非阻塞方式
StartWorking();
CloseSocket(socket_id);
printf("\r\nSocket %d is Closed\r\n",socket_id);
memset(&system_data.TreadCtrl_t[i],0,sizeof(system_data.TreadCtrl_t[i]));
return 0;
}
unsigned long __stdcall ListenThread(void * para)
{
int s,connector;
int child;
struct NETSERVERCTL_t * q;
(int)q = (int)para; // 使 q 指向对应的记录
s = OpenSocket(2); // 打开一个监听 SOCKET
if (s < 1)
{
return 0; // 若失败就退出
}
q[0].FatherSocket = s; // 若成功,记录句柄
if (BindSocket(s,q[0].PortNumber) == 0) // 与端口联系起来
{
if (ListenSocket(s) == 0) // 监听
for (;;)
{
child=AcceptSocket(s,&connector); // 与一个客户端连上
if (child < 1)
{
break; // 若异常就退出
}
q[0].ChildSocket[q[0].Head] = child;
q[0].Connector[q[0].Head] = connector;
q[0].Head++;
if (q[0].Head >= 8)
{
q[0].Head = 0;
}
NetClientConnectScan();
}
}
CloseSocket(s);
q[0].FatherSocket = 0; // 句柄清零
q[0].ThreadHandle = 0; // 句柄清零
return 0;
}
//-------------------------------------------------------------------------
// 初始化
// 创建监听线程
//-------------------------------------------------------------------------
int FsmNetServerInit(int port)
{
uint32 ThreadID;
TCPIP_init();
if (port)
{
if (system_data.NetServer[0].ThreadHandle != 0)
{
TerminatePhysicalThread(system_data.NetServer[0].ThreadHandle);
CloseSocket(system_data.NetServer[0].FatherSocket);
system_data.NetServer[0].ThreadHandle = 0;
system_data.NetServer[0].FatherSocket = 0;
}
system_data.NetServer[0].PortNumber = port;
system_data.NetServer[0].Type = THREADTYPE_SOCKET;
system_data.NetServer[0].ThreadHandle =
CreatePhysicalThread(ListenThread,
(int *)&system_data.NetServer[0],
&ThreadID
);
if(system_data.NetServer[0].ThreadHandle)
{
ResumeThread((HANDLE)system_data.NetServer[0].ThreadHandle);
SetThreadPriority((HANDLE)system_data.NetServer[0].ThreadHandle,
THREAD_PRIORITY_HIGHEST);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -