📄 echosrv.c
字号:
}
// 开始读取
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 + -