2024年5月25日发(作者:)

在linux下连接MSSQL是一件很痛苦的事,因为微软同志没有提供任何接口给开发人

员,还好,MSSQL是从Sybase衍生出来的,FreeTDS是一个数据库底层的驱动程序,用freetds

的库进行开发是一件很方便的事。freetds可以连接sybase和ms sql server数据库。

FreeTDS的安装与配置

官方网站:

版本:0.64

下载地址:/pub/Linux/ALPHA/freetds/stable/

这个软件能够用Linux和Unix连接MS SQLServer和Sybase数据库。

安装与配置

1编译安装freetds:

$ tar zxvf (解压)

$ ./configure --prefix=/usr/local/freetds --with-tdsver=8.0 --enable-msdblib

$ make

$ make install

解释:

安装freetds到目录/usr/local/freetds:--prefix=/usr/local/freetds

支持MSSQL2000:--with-tdsver=8.0 --enable-msdblib

--with-tdsver是设置TDS版本,--enable-msdblib为是否允许Microsoft数据库函数库:

2配置FreeTds的库文件

将freetds的库文件所在路径配置到LD_LIBRARY_PATH参数中:

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/freetds/lib/:

3设置bin路径

$vi /root/.bashrc

添加内容如下:

export FREETDS=/usr/local/freetds

export $PATH="$PATH:$FREETDS/bin"

FreeTDS默认安装在/usr/local/freetds目录当中,库文件在相应的lib目录下。

4编辑/etc/,在其中插入一行:

/usr/local/freetds/lib

5然后运行以下指令使更改生效:

ldconfig

6这样基本OK,不够我们还有配置下/etc/ 文件,按照文件帮助加入自己MSSQL

的IP及其配置信息。下面,我列出我的 MS 2000 配置信息。

# A typical Microsoft SQL Server 2000 configuration

[IBMSQL]

host = 192.168.1.158

port =1433

tds version 8.0

呵呵,简单吧,其实就是把你的 SQL2000 数据库 及1433 端口(MS SQL均为1433端口)

与IBMSQL这个符号名捆绑一下。当然不配置这些参数其实也可以访问MS SQL的。

7.在目录/usr/local/freetds/bin键入:

./tsql -H192.168.1.158 -p1433 -Usa -Pabc123

tsql -H MSSQL服务器服务IP -p 1433 -U MSSQL服务器登陆帐号 -P MSSQL服务器登陆密

码,剩下如果输出:> 则代表你成功了。

>use Tomonitor

>go

>select * from tb_abc

>go

8.总结:刚开始我安装好freetds后老是访问不了MSSQL,所以大家的MSSQL2000 一定要

升级到SP4(sp3估计也可以);最大的喜讯是:freetds-0.63 支持中文了。可以查询出中文

信息,而不是使用?号代替了。呵呵,爽一个字了的。

对了,我用它访问我的Linux下Sybase数据库,也非不错。

testsybase.c

#include

#include

#include

#define SQLDBIP "192.168.1.158" //数据库IP

#define SQLDBPORT "1433" //数据库端口号

#define SQLDBNAME "Tomonitor" //数据库名

#define SQLDBUSER "sa" //数据库登录名

#define SQLDBPASSWD "abc123" //数据库登录密码

#define SQLDBCMD "select aa,bb,cc from tb_abc"

#define SQLDBSERVER SQLDBIP":"SQLDBPORT

int main()

{

printf("aaaaaaaaaaaaaaaaaan");

LOGINREC *loginrec;

DBPROCESS *dbprocess;

char DBTable_id[100];

char DBTable_name[250];

char DBTable_description[250];

dbinit(); //init db_library

loginrec = dblogin();

DBSETLUSER(loginrec,SQLDBUSER);

DBSETLPWD(loginrec,SQLDBPASSWD);

if((dbprocess = dbopen(loginrec,SQLDBSERVER)) == FAIL)

{

printf("SQLDB: Conect MS SQL SERVER Failn");

return 1;

}

printf("SQLDB: ConnectEMS Conect MS SQL SERVER Successn");

if(dbuse(dbprocess,SQLDBNAME) == FAIL)

{

printf("SQLDB: Open database name Failn");

return 1;

}

printf("SQLDB: Open database name Successn");

dbcmd(dbprocess,SQLDBCMD);

if(dbsqlexec(dbprocess) == FAIL)

{

printf("SQLDB: Select EXEC SQL sentence Errorn");

dbclose(dbprocess);

return 1;

}

printf("%-10s%-20s%-20sn","ID","NAME","Description");

memset(DBTable_id,'0',sizeof(DBTable_id));

memset(DBTable_name,'0',sizeof(DBTable_name));

}

memset(DBTable_description,'0',sizeof(DBTable_description));

if(dbresults(dbprocess) == SUCCEED)

{

dbbind(dbprocess,1,CHARBIND,(DBINT)0,(BYTE*)DBTable_id);

dbbind(dbprocess,2,CHARBIND,(DBINT)0,(BYTE*)DBTable_name);

dbbind(dbprocess,3,CHARBIND,(DBINT)0,(BYTE*)DBTable_description);

}

while(dbnextrow(dbprocess)!=NO_MORE_ROWS)

{

printf("%st",DBTable_id);

printf("%st",DBTable_name);

printf("%sn",DBTable_description);

}

char aa[30];

strcpy(aa,"insert into tb_abc(aa,bb,dd) values('23d','fwe','few')");

/*strcpy(aa,"update tb_abc set aa='abcabcabcabc' where id=");

char id[5];

int ID=2;

sprintf(id,"%d",ID);

strcat(aa,id);

strcat(aa,"");

printf("aa is:%sn",aa);*/

dbcmd(dbprocess,aa);

//dbcmd(dbprocess,"insert into tb_abc(aa,bb,dd) values('32d','fer3w','43r')");

if(dbsqlexec(dbprocess) == FAIL)

{

printf("SQLDB: insert EXEC SQL sentence Errorn");

dbclose(dbprocess);

return 1;

}

printf("SQLDB: insert EXEC SQL sentence Sucessn");

dbclose(dbprocess);

return 0;

编译: gcc -o testsybase testsybase.c -I/usr/local/freetds/include -L/usr/local/freetds/lib -lsybdb

如果出现如下错误: error while loading shared libraries:.5:cannot open……

则表示路径没有设置对,你这要用命令echo $LD_LIBRARY_PATH 查看路径是否正确,

如果为空 则查看上面2 、3、4、5是否设置好 !

网络聊天室服务器端源代码

UNIX编程 2006-08-31 10:49:50 阅读43 评论0 字号:大中小

//项目名称:网络聊天系统(服务器端)

//作者:张东生 日期:2006年8月

#include

/*..................Socket编程需要用到的头文件.....................*/

#include //数据类型定义

#include //提供socket函数及数据结构

#include

#include

#include

#include

#include

#include

#include

#include //定义数据结构sockaddr_in

#include

#include

#include

#include

#include

#include //提供错误号errno的定义,用于错误处理

#include //提供进程等待的函数

#include

/*...............连接数据库需要用到的头文件........*/

#include

#include

#define SERVPORT 6667 /*服务器监听端口号 */

#define BACKLOG 10 /* 最大同时连接请求数 */

#define DATASIZE 100

/*收到如下宏信息时进入相应处理模块进行相关操作*/

#define LOGIN "LOGIN" //客户端登陆

#define REGIST "REGIST" //客户端注册

#define ENTERROOM "ENTERROOM" //客户端进入一个房间

#define QUIT "QUIT" //客户端退出程序

#define QUITROOM "QUITROOM" //客户端退出房间

#define FAILURE "FAIL" //客户端登陆失败返回信息

#define SUCCESS "SUCCEED" //客户端登陆成功返回信息

#define CHAT "MESSAGE" //要求聊天

#define ONLINEUSERINFO "ONLINE" //发送在线用户列表

//注册信息结构体

struct regist{

char name[20];

char password[10];

char area[10];

char city[8];

char phone[15];

char email[30];

int sex;

char age[3];

char bloodtype[4];

char shengxiao[2];

char star[6];

char job[20];

char page[50];

char introduce[160];

};

//在线用户列表结构体

struct Online{

char name[20];

char ID[10];

};

//某用户退出房间时向本房间发送该用户信息的用户信息结构体

struct QuitRoomUserInfo{

char name[20];

char ID[10];

};

//聊天信息结构体

struct message{

char from[20]; //发送端用户

char toID[10];//接收端用户ID

char to[20];//接收端用户

int isprivate;//是否私聊1为是0为不是

int index; //表情的索引值

char mess[1024];//聊天内容

};

void RegistUserInfo(struct regist UserInfo,int client_fd); //用户注册处理函数

char* CheckUserInfo(char* LoginInfo,int client_fd); //用户登陆处理函数

void EnterRoom(char* roomNo,int client_fd,char *userid); //用户进入某个房间处理函数

void Chat(struct message chatmsg,char* userid,char* roomNo); //用户聊天处理函数

void Quit(char* userid); //用户退出程序处理函数

void QuitRoom(char* userid,char* RoomNo); //用户退出房间处理函数

main()

{

int sockfd,client_fd;

struct sockaddr_in my_addr;

struct sockaddr_in remote_addr;

socklen_t sin_size;

int recvbytes;

char buf[100],LoginInfo[30],RoomNo[10]; //登陆信息(NAME,ID)以及房间号

char userid[10]; //保存用户注册时的id

char* buff=NULL;

pthread_t id;

int ret;

struct regist UserInfo;

struct message Chatmsg;

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){ //创建SOCKET

printf("Create socket error!n");

exit(1);

}

printf("Create socket succeed!n");

my__family=AF_INET;

my__port=htons(SERVPORT);

my__addr.s_addr=INADDR_ANY;

bzero(&(my__zero),8);

//与本地地址绑定

if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1){

printf("bind error!n");

exit(1);

}

printf("bind ok!n");

//在端口侦听

if(listen(sockfd,BACKLOG)==-1){

printf("listen error!n");

exit(1);

}

printf("");

while(1){

sin_size=sizeof(struct sockaddr_in);

//当有客户端连接时接受连接

if((client_fd=accept(sockfd,(struct sockaddr*)&remote_addr,&sin_size))==-1){

printf("accept error!n");

return;

}

printf("received a connection from %sn",inet_ntoa(remote__addr));

//创建一个进程,负责与一个客户端的连接

if(!fork()){

for(;;){

buff=inet_ntoa(remote__addr); //记下该客户端IP

memset(buf,'0',sizeof(buf));

if((recvbytes=recv(client_fd,buf,100,0))==-1)

{

printf("客户端%s recv出错!n",buff);

Quit(userid);

close(client_fd);

exit(1);

}

buf[recvbytes]='0';

//如果是注册......

if(!strcmp(buf,REGIST))

{

if((recvbytes=recv(client_fd,(char* )&UserInfo,sizeof(struct regist),0))==-1)

{

printf("客户端%s UserInfo recv出错!n",buff);

close(client_fd);

break;

}

else

{

printf("%sn%sn%sn%sn%sn%sn%sn%sn%sn%sn%sn%sn%sn",,

rd,,,,

,,ype,iao,,UserInf

,,uce);

// printf("%sn%sn%sn",ype,iao,);

printf("UserInfo recv succeed!n");

RegistUserInfo(UserInfo,client_fd);

}

}

//如果是登陆......

else if(!strcmp(buf,LOGIN))

{

if((recvbytes=recv(client_fd,LoginInfo,sizeof(LoginInfo),0))==-1)

{

printf("客户端%s 登陆信息 recv出错!n",buff);

close(client_fd);

break;

}

else

{

printf("%dn",client_fd);

LoginInfo[recvbytes]='0';

memset(userid,'0',sizeof(userid));

strcpy(userid,CheckUserInfo(LoginInfo,client_fd));

printf("ID:%sn",userid);

}

}

//如果是进入一个房间......

else if(!strcmp(buf,ENTERROOM))

{

if((recvbytes=recv(client_fd,RoomNo,sizeof(RoomNo),0))==-1)

{

printf("客户端%s 登陆信息 recv出错!n",buff);

close(client_fd);

break;

}

else

{

printf("ID:%sn",userid);

printf("UserRoomNO:%sn",RoomNo);

EnterRoom(RoomNo,client_fd,userid);

}

}

//如果是退出程序......

else if(!strcmp(buf,QUIT))

{

Quit(userid);

}

//如果是退出某个房间.....

else if(!strcmp(buf,QUITROOM))

{

printf("ID:%sn",userid);

printf("UserRoomNO:%sn",RoomNo);

QuitRoom(userid,RoomNo);

}

//如果是聊天......

else if(!strcmp(buf,CHAT))

{

if((recvbytes=recv(client_fd,(char* )&Chatmsg,sizeof(struct message),0))==-1)

{

printf("客户端%s 聊天信息 recv出错!n",buff);

close(client_fd);

break;

}

else

{

printf("RoomNo:%sn",RoomNo);

printf("isprivate:%dn",ate);

Chat(Chatmsg,userid,RoomNo);

}

}

else

{

}

}

}

}

}

/*************************************************

Function: void RegistUserInfo(struct regist UserInfo,int client_fd)

Description: 用户注册处理函数

首先连接数据库,查找数据库里的记录数,将记录数+1+10000作为新注册用户的ID,

然后将用户注册信息插入数据库,其中UserOnline,UserSocketNO,UserRoomNO都

初始化为0

最后把以#ID#PASSWORD的形式将用户注册的ID及密码发送给用户

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated: T_USERINFO

Input: struct regist UserInfo 用户注册信息结构体

int client_fd 客户端SOCKET

Output: 先向客户端发送一个字符串"REGIST",然后在向客户端发送一个格式为

#ID#PASSWORD

包含ID和密码信息的字符串

Return:

Others:

*************************************************/

void RegistUserInfo(struct regist UserInfo,int client_fd)

{

//.........连接数据库..........

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE resultcode;

DBCHAR nick[20];

int j;

int U_Id=0;

char RegistInfo[1024]; //存放SQL语句

char ReInfo[30]; //存放返回的ID和密码信息

char str[10];

memset(RegistInfo,'0',1024);

strcpy(RegistInfo,"select* from T_USERINFO");

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

dbcmd(dbproc,RegistInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("dbsqlexec succeed!n");

//查找数据库里的记录数,将记录数+1+10000作为新注册用户的ID

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS){

if(resultcode==SUCCEED){

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

U_Id++;

}

}

}

printf("%dn",U_Id);

U_Id++;

U_Id=U_Id+10000;

memset(RegistInfo,'0',sizeof(RegistInfo));

printf("%dn",U_Id);

strcpy(RegistInfo,"insert into

T_USERINFO(UserName,UserID,UserPassword,UserArea,UserCity,");

strcat(RegistInfo,"UserPhone,UserEmail,UserSex,UserAge,UserBloodtype,UserShengxia

o,UserStar,");

strcat(RegistInfo,"UserJob,UserPage,UserIntroduce,UserOnline,UserSocketNO,UserRoo

mNO) values('");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

sprintf(str,"%d",U_Id); //将整型的U_Id转化为字符型

strcat(RegistInfo,str);

strcat(RegistInfo,"','");

strcat(RegistInfo,rd);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"',");

sprintf(str,"%d",);

strcat(RegistInfo,str);

strcat(RegistInfo,",'");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,ype);

strcat(RegistInfo,"','");

strcat(RegistInfo,iao);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,);

strcat(RegistInfo,"','");

strcat(RegistInfo,uce);

strcat(RegistInfo,"',");

strcat(RegistInfo,"0");

strcat(RegistInfo,",");

strcat(RegistInfo,"0");

strcat(RegistInfo,",");

strcat(RegistInfo,"0");

strcat(RegistInfo,")");

printf("%sn",RegistInfo);

dbcmd(dbproc,RegistInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("dbsqlexec succeed!n");

memset(ReInfo,'0',20);

strcpy(ReInfo,"#");

sprintf(str,"%d",U_Id);

strcat(ReInfo,str);

strcat(ReInfo,"#");

strcat(ReInfo,rd);

printf("%sn",ReInfo);

if(send(client_fd,REGIST,sizeof(REGIST),0)==-1){

printf("返回注册信息出错!n");

close(client_fd);

return;

}

//以#ID#PASSWORD的形式将用户注册的ID及密码发送给用户

if(send(client_fd,ReInfo,sizeof(ReInfo),0)==-1){

printf("返回注册信息出错!n");

close(client_fd);

return;

}

printf("ID为%d的用户注册成功!n",U_Id);

dbexit(); //关闭数据库连接

}

/*************************************************

Function: char* CheckUserInfo(char* LoginInfo,int client_fd)

Description: 用户登陆处理函数

首先对客户端发来的格式为#ID#PASSWORD包含用户ID和密码的字符串进行处理,

提取出ID和密码

然后连接数据库,查找数据库中是否ID和密码都相同的记录,如果有,则向客户端发送

登陆失败信

息,否则,向客户端发送登陆成功信息.如果登陆成功,则更新该数据库中该ID对应的信

息,将

字段UserOnline=1,UserSocketNO设置为该客户端的SOCKET值

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated:

Input: char* LoginInfo 客户端发来的格式为#ID#PASSWORD包含用户ID

和密码的字符串

int client_fd 客户端SOCKET

Output: 先向客户端发送一个字符串"LOGIN",然后在向客户端发送"FAIL"(登陆

失败),"SUCCESS"(登陆成功)

的字符串

Return: 返回登陆成功的用户的ID

Others:

*************************************************/

char* CheckUserInfo(char* LoginInfo,int client_fd)

{

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE resultcode;

char str[10];

char *AssayInfo=LoginInfo; //存入用户的登陆信息

char id[20]; //保存用户ID

char password[20]; //保存用户的密码

int i=0,j=0;

int flag=0; //用户是否登陆成功的标志位

char CheckInfo[100]; //存放SQL语句

char ReInfo[20]; //存放登陆成功或失败信息

memset(id,'0',20);

memset(password,'0',20);

//对接收的#ID#PASSWORD的字符串进行处理,提取出其中的ID和PASSWORD

do{

AssayInfo++;

if(*AssayInfo=='#'){

AssayInfo++;

while(*AssayInfo!='0'){

password[i]=*AssayInfo;

i++;

AssayInfo++;

}

break;

}

else

{

id[j]=*AssayInfo;

j++;

}

}while(1);

printf("ID为%s的用户正在登陆......n",id);

memset(CheckInfo,'0',100);

strcpy(CheckInfo,"select* from T_USERINFO where UserID='");

strcat(CheckInfo,id);

strcat(CheckInfo,"'");

strcat(CheckInfo," and UserPassword='");

strcat(CheckInfo,password);

strcat(CheckInfo,"'");

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

dbcmd(dbproc,CheckInfo);

dbsqlexec(dbproc);

//判断登陆是否成功

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS){

if(resultcode==SUCCEED)

{

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

flag++;

}

}

}

if(send(client_fd,LOGIN,sizeof(LOGIN),0)==-1){

printf("返回登陆失败信息出错!n");

close(client_fd);

return;

}

//如果登陆失败.....

if(!flag){

memset(ReInfo,'0',20);

strcpy(ReInfo,FAILURE);

if(send(client_fd,ReInfo,sizeof(ReInfo),0)==-1){

printf("返回登陆失败信息出错!n");

close(client_fd);

return;

}

printf("ID为%s的用户登陆失败!n",id);

}

//登陆成功.....

else

{

memset(ReInfo,'0',20);

strcpy(ReInfo,SUCCESS);

if(send(client_fd,ReInfo,sizeof(ReInfo),0)==-1){

printf("返回登陆成功信息出错!n");

close(client_fd);

return;

}

memset(CheckInfo,'0',100);

//更新用户信息

strcpy(CheckInfo,"Update T_USERINFO set UserOnline=1,UserSocketNO=");

sprintf(str,"%d",client_fd);

strcat(CheckInfo,str);

strcat(CheckInfo," where UserID='");

strcat(CheckInfo,id);

strcat(CheckInfo,"'");

dbcmd(dbproc,CheckInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("ID为%s的用户登陆成功!n",id);

printf("%sn",id);

}

dbexit();

return id; //返回登陆成功的用户ID

}

/*************************************************

Function: void EnterRoom(char* roomNo,int client_fd,char* userid)

Description: 用户进入某个房间的处理函数

首先连接数据库,将该ID在数据库中的字段UserRoomNO设置为传进的房间号,

然后查找UserOnline=1,即在线以及在此房间的用户的ID和NAME,并存入Online

结构体,然后查找UserOnline=1,即在线以及在此房间的用户的SOCKET,先向这些

SOCKET发送"ONLINE"字符串,然后发送存有在此房间的在线用户信息的Online结

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated: T_USERINFO

Input: char* roomNo 客户端发来的格式房间号

int client_fd 客户端SOCKET

char* userid 登陆时记下的ID

Output: 数据库连接成功信息,发送用户列表成功信息

Return:

Others:

*************************************************/

void EnterRoom(char* roomNo,int client_fd,char* userid)

{

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE resultcode;

char EnterRoomInfo[255]; //存放SQL语句

char Username[20]; //存放用户NAME

char Userid[10]; //存放ID

struct Online OnlineUserInfo[30]; //存放在线用户列表的结构体数组

char Stringclient[30]; //存放SOCKET

int client; //存放SOCKET

int i=0,j,m;

char str[10];

for(m=0;m<30;m++)

{

memset(&OnlineUserInfo[m],0,sizeof(struct Online)); //初始化结构体数组

}

memset(EnterRoomInfo,'0',sizeof(EnterRoomInfo));

strcpy(EnterRoomInfo,"update T_USERINFO set UserRoomNO=");

strcat(EnterRoomInfo,roomNo);

strcat(EnterRoomInfo," where UserID='");

strcat(EnterRoomInfo,userid);

strcat(EnterRoomInfo,"'");

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

dbcmd(dbproc,EnterRoomInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Update EnterRoom() Error:dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("ID为%s的用户进入%s号房间n",userid,roomNo);

memset(EnterRoomInfo,'0',sizeof(EnterRoomInfo));

strcpy(EnterRoomInfo,"select UserName,UserID from T_USERINFO where

UserOnline=1 and UserRoomNO=");

strcat(EnterRoomInfo,roomNo);

printf("%sn",EnterRoomInfo);

dbcmd(dbproc,EnterRoomInfo);

dbsqlexec(dbproc);

printf("SUCCEED:select UserName dbsqlexec successn");

//将查询到的在本房间的在线用户的NAME和ID保存到在线用户列表结构体数组

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS)

{

if(resultcode==SUCCEED){

dbbind(dbproc,1,NTBSTRINGBIND,(DBINT)0,(BYTE*)Username);

dbbind(dbproc,2,NTBSTRINGBIND,(DBINT)0,(BYTE*)Userid);

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

strcpy(OnlineUserInfo[i].name,Username);

strcpy(OnlineUserInfo[i].ID,Userid);

i++;

}

}

}

printf("I:%dn",i);

for(j=0;j

{

printf("NAME:%sn",OnlineUserInfo[j].name);

printf("ID:%sn",OnlineUserInfo[j].ID);

}

// sprintf(str,"%d",i);

memset(EnterRoomInfo,'0',sizeof(EnterRoomInfo));

strcpy(EnterRoomInfo,"select UserSocketNO from T_USERINFO where UserOnline=1

and UserRoomNO=");

strcat(EnterRoomInfo,roomNo);

printf("%sn",EnterRoomInfo);

dbcmd(dbproc,EnterRoomInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:EnterRoom dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("SUCCEED:select socket dbsqlexec successn");

memset(Stringclient,'0',sizeof(Stringclient));

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS)

{

if(resultcode==SUCCEED)

{

dbbind(dbproc,1,STRINGBIND,(DBINT)0,(BYTE* )Stringclient);

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

printf("string:%sn",Stringclient);

sscanf(Stringclient,"%d",&client); //将字符型转化为整型

printf("int:%dn",client);

//发送在线用户列表

if(client)

{

if(send(client,ONLINEUSERINFO,sizeof(ONLINEUSERINFO),0)==-1){

printf("发送用户列表信息出错!n");

// close(client);

// return;

}

printf("发送用户列表信息成功!n");

/* if(send(client,str,sizeof(str),0)==-1){

printf("发送在本房间用户数信息出错!n");

close(client);

return;

}*/

// printf("发送在本房间用户数信息成功!n");

if(send(client,(char* )&OnlineUserInfo,sizeof(OnlineUserInfo),0)==-1){

printf("发送用户信息出错!n");

// close(client);

// return;

}

printf("发送用户信息成功!n");

}

}

}

}

printf("发送在%s号房间的用户信息成功!n",roomNo);

dbexit();

}

/*************************************************

Function: void Chat(struct message chatmsg,char* userid,char* roomNo)

Description: 用户聊天的处理函数

首先连接数据库,查找出在此房间的在线用户的SOCKET,如果不是私聊,则向所有用

发送包含聊天信息的message结构体,如果是私聊,则根据私聊对象的ID找到他的

SOCKET,

然后向此私聊对象发送message结构体

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated:

Input: struct message chatmsg 包含用户聊天信息的结构体

char* roomNo 客户端发来的格式房间号

char* userid 登陆时记下的ID

Output: 数据库连接成功信息,发送聊天信息成功信息

Return:

Others:

*************************************************/

void Chat(struct message chatmsg,char* userid,char* roomNo)

{

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE result_code;

char ChatInfo[100]; //存放SQL

char Stringclient[30]; //字符型SOCKET,存放公共聊天的SOCKET

int client; //整型SOCKET,存放公共聊天的SOCKET

char StringPersonSocket[30]; //字符型SOCKET,存放私聊的SOCKET

int PersonSocket; //整型SOCKET,存放私聊的SOCKET

memset(ChatInfo,'0',sizeof(ChatInfo));

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

printf("isprivate:%dn",ate);

//如果不是私聊,则向所有在本房间的在线用户发送聊天信息

if(!ate){

strcpy(ChatInfo,"select UserSocketNO from T_USERINFO where UserOnline=1 and

UserRoomNO=");

strcat(ChatInfo,roomNo);

dbcmd(dbproc,ChatInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:Chat dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("!ate dbexesql succeedn");

memset(Stringclient,'0',sizeof(Stringclient));

while((result_code=dbresults(dbproc))!=NO_MORE_RESULTS)

{

if(result_code==SUCCEED)

{

dbbind(dbproc,1,STRINGBIND,(DBINT)0,(BYTE*)Stringclient);

printf("client here!n");

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

sscanf(Stringclient,"%d",&client);

if(client)

{

if(send(client,CHAT,sizeof(CHAT),0)==-1){

printf("发送CHAT信息出错!n");

// close(client);

// return;

}

if(send(client,(char* )&chatmsg,sizeof(struct message),0)==-1){

printf("发送message信息出错!n");

// close(client);

// return;

}

}

printf("%dn",client);

}

}

}

}

//如果是私聊,则向要聊天的聊天对象发送聊天信息

else

{

printf("isprivate=1n");

printf("isprivate:%dn",ate);

memset(ChatInfo,'0',sizeof(ChatInfo));

strcpy(ChatInfo,"select UserSocketNO from T_USERINFO where UserID='");

strcat(ChatInfo,);

strcat(ChatInfo,"'");

dbcmd(dbproc,ChatInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:QuitRoom dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

while((result_code=dbresults(dbproc))!=NO_MORE_RESULTS)

{

if(result_code==SUCCEED)

{

dbbind(dbproc,1,STRINGBIND,(DBINT)0,(BYTE*)StringPersonSocket);

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

sscanf(StringPersonSocket,"%d",&PersonSocket);

if(send(PersonSocket,CHAT,sizeof(CHAT),0)==-1){

printf("发送CHAT信息出错!n");

// close(PersonSocket);

// return;

}

if(send(PersonSocket,(char*)&chatmsg,sizeof(struct message),0)==-1){

printf("发送message信息出错!n");

// close(PersonSocket);

// return;

}

}

}

}

}

dbexit();

}

/*************************************************

Function: void Quit(char* userid)

Description: 用户退出程序的处理函数

首先连接数据库,将ID为登陆时记下的ID的用户在数据库中的字段

UserOnline=0,UserSocketNO=0

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated: T_USERINFO

Input:

char* userid 登陆时记下的ID

Output: 数据库连接成功信息,该ID退出登陆信息

Return:

Others:

*************************************************/

void Quit(char* userid)

{

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE resultcode;

char QuitInfo[100];

memset(QuitInfo,'0',sizeof(QuitInfo));

strcpy(QuitInfo,"update T_USERINFO set UserOnline=0,UserSocketNO=0 where

UserID='");

strcat(QuitInfo,userid);

strcat(QuitInfo,"'");

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

dbcmd(dbproc,QuitInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:Quit dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

printf("ID为%s的用户退出登录!n",userid);

dbexit();

}

/*************************************************

Function: void QuitRoom(char* userid,char* RoomNo)

Description: 用户退出某个房间的处理函数

首先连接数据库,将ID为登陆时记下的ID的用户在数据库中的字段

UserRoomNO=0,然后查找出该用户名字,将其NAME和ID存入quitroom

结构体,然后查找出在此房间的在线用户的SOCKET,并向他们发送包

含NAME和ID的quitroom结构体

Calls:

Called By: main()

Table Accessed: T_USERINFO

Table Updated: T_USERINFO

Input: char* userid 登陆时记下的ID

char* roomNo 客户端发来的格式房间号

Output: 数据库连接成功信息,该ID退出该房间成功信息

Return:

Others:

*************************************************/

void QuitRoom(char* userid,char* RoomNo)

{

DBPROCESS *dbproc;

LOGINREC *login;

RETCODE resultcode;

char Stringclient[30]; //保存查询到的SOCKET

int client; //保存查询到的SOCKET

int i=0;

char Quit[10]; //发送的QUITROOM信息

char username[20]; //保存用户的NAME

struct QuitRoomUserInfo quitroom; //保存用户NAME和ID的结构体

char QuitInfo[100]; //存放SQL语句

memset(QuitInfo,'0',100);

strcpy(QuitInfo,"update T_USERINFO set UserRoomNO=0 where UserID='");

strcat(QuitInfo,userid);

strcat(QuitInfo,"'");

if(dbinit()==FAIL) exit(ERREXIT);

login=dblogin();

DBSETLUSER(login,"sa");

DBSETLPWD(login,"");

dbproc=dbopen(login,"phs");

if(dbproc==(DBPROCESS*)NULL)

{

printf("can not connect server!n");

exit(FAIL);

}

printf("database connect succeed!n");

dbuse(dbproc,"staticdb");

dbcmd(dbproc,QuitInfo);

dbsqlexec(dbproc);

memset(QuitInfo,'0',100);

strcpy(QuitInfo,"select UserName from T_USERINFO where UserID='");

strcat(QuitInfo,userid);

strcat(QuitInfo,"'");

dbcmd(dbproc,QuitInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:QuitRoom dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS){

if(resultcode==SUCCEED)

{

dbbind(dbproc,1,STRINGBIND,(DBINT)0,(BYTE*)username); //把查找到的NAME存

入username

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

strcpy(,username);

}

}

}

strcpy(,userid); //用quitroom结构体保存退出该房间的用户的ID和NAME

memset(QuitInfo,'0',100);

strcpy(QuitInfo,"select UserSocketNO from T_USERINFO where UserOnline=1 and

UserRoomNO=");

strcat(QuitInfo,RoomNo);

dbcmd(dbproc,QuitInfo);

if(dbsqlexec(dbproc)==FAIL){

printf("Error:QuitRoom dbsqlexec failedn");

dbexit();

exit(ERREXIT);

}

while((resultcode=dbresults(dbproc))!=NO_MORE_RESULTS){

if(resultcode==SUCCEED)

{

dbbind(dbproc,1,STRINGBIND,(DBINT)0,(BYTE*)Stringclient);

while(dbnextrow(dbproc)!=NO_MORE_ROWS)

{

sscanf(Stringclient,"%d",&client);

printf("client:%dn",client);

memset(Quit,'0',sizeof(Quit));

strcpy(Quit,"QUIROOM");

//向查找到的在此房间的在线用户发送退出房间信息

if(client)

{

if(send(client,Quit,sizeof(Quit),0)==-1){

printf("发送退出信息出错!n");

close(client);

return;

}

if(send(client,(char* )&quitroom,sizeof(struct QuitRoomUserInfo),0)==-1){

printf("发送退出信息出错!n");

close(client);

return;

}

}

}

}

}

printf("ID为%s的用户退出%s号房间成功!n",userid,RoomNo);

dbexit();

}