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

📄 echosrv.c

📁 VC做的C/S考试系统
💻 C
📖 第 1 页 / 共 3 页
字号:
            }

            // 开始读取
            IssueRead(pCntx);
        }
    }

    return 0;
}


/*
 *  调用 ReadFile 开始一个异步请求
 *  重复获取我们的句柄状态
 */
void IssueRead(struct ContextKey *pCntx)
{
    int     i = 0;
    BOOL    bResult;
    int     err;
    int     numRead;

    while (++i)
    {
        // 读取一个单字符
        bResult = ReadFile(
                    (HANDLE)pCntx->sock,
                    pCntx->InBuffer,
                    1,
                    &numRead,
                    &pCntx->ovIn
                );

        // 这里,等待一个信息包.
        if (bResult)
            return;

        err = GetLastError();

        // 获取状态,这里并不代表错误
        if (err == ERROR_IO_PENDING)
            return;

        if ( err == ERROR_INVALID_USER_BUFFER ||
             err == ERROR_NOT_ENOUGH_QUOTA ||
             err == ERROR_NOT_ENOUGH_MEMORY )
        {
            if (i == 5) 
            {
                Sleep(50);  // 等待并重试
                continue;
            }

            FatalError("IssueRead -系统溢出连接池");
        }

        break;
    }

    fprintf(stderr, "IssueRead - 读信息失败.\n");
}

//
// 确保我们运行在正确的版本下 Windows NT (3.51, 4.0, or later)
//
void CheckOsVersion()
{
    OSVERSIONINFO   ver;
    BOOL            bResult;

    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    bResult = GetVersionEx((LPOSVERSIONINFO) &ver);

    if ( (!bResult) ||
         (ver.dwPlatformId != VER_PLATFORM_WIN32_NT) )
    {
        FatalError("ECHOSRV requires Windows NT 3.51 or later.");
    }

}

//发送字符串子程序
void SendString(char *p,struct ContextKey *pCntx)
{
	          int len;
			  strcpy(pCntx->OutBuffer,p);
	          len=strlen(pCntx->OutBuffer);
	          pCntx->OutBuffer[len++]='\n';
              pCntx->OutBuffer[len]='\0';
	          pCntx->nOutBufIndex=strlen(pCntx->OutBuffer);
              WriteFile(
                        (HANDLE)(pCntx->sock),
                        pCntx->OutBuffer,
                        pCntx->nOutBufIndex,
                        &pCntx->dwWritten,
                        &pCntx->ovOut
                    );

}

//
// 错误句柄
//
void FatalError(char *s)
{
    fprintf(stdout, "%s\n", s);
    exit(EXIT_FAILURE);
}

//数据库联接函数
void ODBCConnect(SCHAR *strConnect,SCHAR *ProgPath,SCHAR *DBName)
{
	SWORD StrLen;                                                             //返回缓冲区长度
    SQLRETURN RB;                                                             //ODBC函数返回错误校验变量
	strcat(ConnectString,strConnect);
    strcat(ConnectString,ProgPath);
	strcat(ConnectString,DBName);

	RB=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,&hEnv);                  //获取环境句柄
	if (RB==SQL_SUCCESS || RB==SQL_SUCCESS_WITH_INFO)
	{
	  RB=SQLSetEnvAttr(hEnv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,0); //设置OBDC启用版本
	  if (RB==SQL_SUCCESS || RB==SQL_SUCCESS_WITH_INFO)
	  {
	    RB=SQLAllocHandle(SQL_HANDLE_DBC,hEnv,&hConn);                         //获取连接句柄
	    if (RB==SQL_SUCCESS || RB==SQL_SUCCESS_WITH_INFO)
		   {
	         RB=SQLDriverConnect(hConn,NULL,(LPSTR)ConnectString,(SQLSMALLINT)strlen(ConnectString),(LPSTR)Conn,(SQLSMALLINT)strlen(Conn),&StrLen,SQL_DRIVER_NOPROMPT);  //联接OBDC驱动程序
	         if (RB==SQL_SUCCESS || RB==SQL_SUCCESS_WITH_INFO)
		        printf("\n学生考试系统数据库连接成功:\n%s%s\n\n",ProgPath,DBName);
	          else 
				{
		          SQLFreeHandle(SQL_HANDLE_DBC, hConn);                        //释放句柄
	              SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
		          FatalError("ODBC驱动程序连接失败!\n");
				}
			}
	     else
			 {
	    	  SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
              FatalError("ODBC连接句柄获取失败!\n");
			 }
	  }
	  else
	  {
            SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
	        FatalError("设置ODBC工作版本失败!\n");
	   }
	}
	else
       FatalError("ODBC环境句柄获取失败!\n");
}

//登陆操作函数
BOOL LoginSever(char * LpText,struct User *login,char *p)
{
  SQLINTEGER PassLength;            //返回缓冲区长度
  SQLHANDLE hStmt;                  //ODBC语句句柄
  SQLRETURN RC;                     //ODBC函数返回错误校验变量
  char * Temp;
  char Attribute[50];
  char *SQLStatement="select 用户等级 from 用户管理 where 科目=? and 账号=? and 密码=?";

  LpText+=6;
  Temp=LpText;
  while(*Temp)
  {
  if(*Temp=='#')
  *Temp='\0';
  Temp++;
  }
  strcpy(login->Subject,LpText);
  LpText+=(strlen(LpText)+1);
  strcpy(login->Name,LpText);
  LpText+=(strlen(LpText)+1);
  strcpy(login->PassWord,LpText);
  
  fprintf(stderr, "\n*****************************\n");
  fprintf(stderr, "用户:%s............请求登陆.\n",login->Name);
  fprintf(stderr, "科目:%s \n",login->Subject);
  fprintf(stderr, "密码/考号:%s\n",login->PassWord);

  RC=SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
  if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
  {
      SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,login->Subject,strlen(login->Subject),NULL);
	  SQLBindParameter(hStmt,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,login->Name,strlen(login->Name),NULL);
	  SQLBindParameter(hStmt,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,login->PassWord,strlen(login->PassWord),NULL);
	  SQLPrepare(hStmt,SQLStatement,strlen(SQLStatement));
      RC=SQLExecute(hStmt);
      if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
	  {
        SQLBindCol(hStmt,1,SQL_C_CHAR,Attribute,strlen(Attribute),&PassLength);
        if(SQLFetch(hStmt)==SQL_NO_DATA)
		{
        fprintf(stderr, "用户登陆失败.\n");
		fprintf(stderr, "*****************************\n\n");
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		return 0;
		}
		fprintf(stderr, "用户登陆成功.\n");
        fprintf(stderr, "用户属于\"%s\".\n",Attribute);
		fprintf(stderr, "*****************************\n\n");
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
	    strcpy(p,Attribute);
		return 1;
	  }
      else
	  {
	   SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
	   fprintf(stderr,"\nSQL语句执行失败\n");
       return 0;
	  }
  }
 else
  {
  fprintf(stderr,"\n语句句柄获取失败\n");
  return 0;
  }
}
//获取试卷状态子程序
BOOL GetState(struct User US,char *p)
{
  char *SQLStatement="select 试卷状态 from 试卷信息表 where 科目名称=?";
  char *SQLStatement2="select 试卷状态 from 学生试卷成绩表 where 科目=? and 姓名=? and 考号=?";
  SQLINTEGER PassLength;            //返回缓冲区长度
  SQLHANDLE hStmt;                  //ODBC语句句柄
  SQLRETURN RC;                     //ODBC函数返回错误校验变量
  char State[5];
  char State2[5];

  RC=SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
  if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
  {
      SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,US.Subject,strlen(US.Subject),NULL);
      RC=SQLExecDirect(hStmt,SQLStatement,strlen(SQLStatement));
      if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
	  {
        SQLBindCol(hStmt,1,SQL_C_CHAR,State,strlen(State),&PassLength);
        if(SQLFetch(hStmt)==SQL_NO_DATA)
		{
        fprintf(stderr, "没有用户所要的 %s 试卷.\n",US.Subject);
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		strcpy(p,"0");
		return 1;
		}
		if(!strcmp(State,"0"))
		{
		fprintf(stderr, "用户所要试卷还未经过审核.\n");
	    strcpy(p,State);
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		return 1;
		}
        SQLFreeStmt(hStmt,SQL_RESET_PARAMS);
        SQLFreeStmt(hStmt,SQL_UNBIND);
        SQLFreeStmt(hStmt,SQL_CLOSE);
		RC=SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,US.Subject,strlen(US.Subject),NULL);
		RC=SQLBindParameter(hStmt,2,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,US.Name,strlen(US.Name),NULL);
        RC=SQLBindParameter(hStmt,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,US.PassWord,strlen(US.PassWord),NULL);
        RC=SQLExecDirect(hStmt,SQLStatement2,strlen(SQLStatement2));
        if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
		{
        SQLBindCol(hStmt,1,SQL_C_CHAR,State2,strlen(State2),&PassLength);
        if(SQLFetch(hStmt)==SQL_NO_DATA)
		{
        fprintf(stderr, "无此用户的试卷信息.\n");
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		return 0;
		}
		strcpy(p,State2);
        fprintf(stderr, "用户获取试卷状态成功.\n");
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		return 1;
		}
	  }
	   SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
	   fprintf(stderr,"\nSQL语句执行失败\n");
       return 0;

  }
 else
  {
  fprintf(stderr,"\n语句句柄获取失败\n");
  return 0;
  }
}

//获取试卷信息子函数
int GetNumbers(struct User US,char *P)
{
  char *SQLStatement="select 建考时间,开考时间,结束时间,监考人,题目数量 from 试卷信息表 where 科目名称=?";
  int Num=0;
  SQLINTEGER   sCustID,sCustID1,sCustID2,sCustID3,sCustID4;             //返回缓冲区长度
  SQLHANDLE hStmt;                                                      //ODBC语句句柄
  SQLRETURN RC;                                                         //ODBC函数返回错误校验变量
  DATE_STRUCT Date;
  TIMESTAMP_STRUCT Time1,Time2;
  char People[20];

  RC=SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
  if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
  {
      SQLBindParameter(hStmt,1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,50,0,US.Subject,strlen(US.Subject),NULL);
      RC=SQLExecDirect(hStmt,SQLStatement,strlen(SQLStatement));
      if (RC==SQL_SUCCESS || RC==SQL_SUCCESS_WITH_INFO)
	  {
		SQLBindCol(hStmt,1,SQL_C_DATE,&Date,0,&sCustID);
		SQLBindCol(hStmt,2,SQL_C_TIMESTAMP,&Time1,0,&sCustID1);
		SQLBindCol(hStmt,3,SQL_C_TIMESTAMP,&Time2,0,&sCustID2);
		SQLBindCol(hStmt,4,SQL_C_CHAR,&People,20,&sCustID3);
        SQLBindCol(hStmt,5,SQL_C_USHORT,&Num,0,&sCustID4);
        if(SQLFetch(hStmt)==SQL_NO_DATA)
		{
        fprintf(stderr, "没有用户所要的 %s 试卷.\n",US.Subject);
		SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
		return 0;
		}
		wsprintf(P,"%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%s",Date.year,Date.month,Date.day,Time1.hour,Time1.minute,Time1.second,Time2.hour,Time2.minute,Time2.second,Num,People);
		return Num;
	  }
	   SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
	   fprintf(stderr,"\nSQL语句执行失败\n");
       return 0;
  }
  fprintf(stderr,"\n语句句柄获取失败\n");
  return 0;
}

//格式化试题子函数
void GetQuestions(struct TestRubric * TestPapers,char * buffers)
{
	int i,n;
    strcpy(buffers,TestPapers->Questions);
    n=strlen(buffers);
	buffers[n++]='#';
	for(i=0;i<4;i++)
	{
	strcpy(&buffers[n],TestPapers->SelectObject[i]);
    n=strlen(buffers);
	buffers[n++]='#';
	}
	buffers[n]='\0';
}

//初始化试卷
BOOL initTestPapers(struct User US,int Num,struct TestRubric * TestPapers)
{
  char *SQLStatement="select 考题序列 from 学生试卷成绩表 where 科目=? and 姓名=? and 考号=?";
  char *SQLStatement2="select * from 题库表 where 题号=?";
  SQLINTEGER PassLength,TestID,TestID2,TestID3,TestID4,TestID5;            //返回缓冲区长度
  SQLHANDLE hStmt;                                                         //ODBC语句句柄

⌨️ 快捷键说明

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