您的位置:首页 > 数据库 > Oracle

linux多线程服务器,用oci API连接Oracle数据库

2009-11-28 16:54 357 查看
这就是我两个星期的成果

server.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <assert.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#define S_PORT 1234
#define LOG_NUM 10
#define MAXDATASIZE 4096

struct client_info{
int connfd;
struct sockaddr_in addr;
};

void* db_process(void* arg);

int main(int argc,char **argv)
{
int listenfd,connfd;
struct sockaddr_in server_addr,client_addr;
int sin_size;

pthread_t thread;
pthread_attr_t attr;

// if(listenfd= socket(AF_INET,SOCK_STREAM, 0)==-1){
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("creating socket failed!");
exit(-1);
}

/*设置socket属性,端口可以重用*/
int opt=SO_REUSEADDR;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(S_PORT);

if(bind( listenfd , (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){
perror("bind socket failed!");
exit(-1);
}

if(listen(listenfd,LOG_NUM)==-1){
perror("listen error!");
exit(-1);
}

sin_size=sizeof(struct sockaddr_in);

while(1){

struct client_info client;
//sin_size=sizeof(struct sockaddr_in);

//if(connfd=accept(listenfd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size)==-1){
if((connfd=accept(listenfd,(struct sockaddr *)&client_addr,(socklen_t *)&sin_size))==-1){
perror("accept error!");
exit(-1);
}

client.connfd=connfd;
client.addr=client_addr;

/*初始化属性值,均设为默认值*/
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
/* 设置线程为分离属性*/
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

if(pthread_create(&thread,&attr,db_process,(void*)&client)){
perror("pthread_creat error!");
exit(-1);
}
}

close(listenfd);
}

void process_cli(int connectfd,struct sockaddr_in *client)
{
int num;
char recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[20];

printf("You got a connection from %s. ",inet_ntoa(client->sin_addr) );
num = recv(connectfd, cli_name, MAXDATASIZE,0);
if (num == 0) {
close(connectfd);
printf("Client disconnected./n");
return;
}
cli_name[num] = '/0';
printf("Client's name is %s./n",cli_name);

while (1){
//bzero(recvbuf,MAXDATASIZE);
num = recv(connectfd, recvbuf, MAXDATASIZE,0);
if (num == 0) {
close(connectfd);
printf("Client(%s) exit./n",cli_name);
return;
}
else if(num < 0){
//printf("recv error! %s : %s /n",errno,strerror(errno));
perror("recv!");
close(connectfd);
return;
}

//recvbuf[num] = '/0';
//printf("num is %d/n",num);
printf("Received client( %s ) message: %s /n",cli_name, recvbuf);
fflush(stdout);

char *s1="insert";
char *s2="select";
int i;

if(!strncmp(s1,recvbuf,6))
oci_insert(recvbuf,sendbuf);
else if(!strncmp(s2,recvbuf,6))
oci_query(recvbuf,sendbuf);
else
sprintf(sendbuf,"input sql is error!/n");

//sendbuf[num] = '/0';
send(connectfd,sendbuf,strlen(sendbuf),0);
printf("return send:%s /n",sendbuf);
fflush(stdout);
bzero(recvbuf,sizeof(recvbuf));
bzero(sendbuf,sizeof(sendbuf));
}
close(connectfd);
}

//接收数据并返回
void* db_process(void* arg)
{
struct client_info *info;
info=arg;
//printf("test........./n");
process_cli(info->connfd, &info->addr);

pthread_exit(NULL);
}

oci_api.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oci.h>
#include "myoci.h"

static OCIEnv *p_env;
static OCIError *p_err;
static OCISvcCtx *p_svc;
static OCIStmt *p_sql;
static OCIDefine *p_dfn = (OCIDefine *) 0;
static OCIBind *p_bnd = (OCIBind *) 0;

int oci_insert(char *sql, char * out)
{
int p_bvi;
char *p_sli;
char *p_sli1;
int rc;
char errbuf[100];
int errcode;
//char mysql[20];
/*
p_sli=(char *)malloc(20);
memset(p_sli,0,20);
p_sli1=(char *)malloc(20);
memset(p_sli1,0,20);
*/
/* Initialize OCI evironment*/
rc = OCIEnvCreate((OCIEnv **) &p_env,OCI_DEFAULT,(dvoid *)0,
(dvoid * (*)(dvoid *, size_t)) 0,
(dvoid * (*)(dvoid *, dvoid *, size_t))0,
(void (*)(dvoid *, dvoid *)) 0,
(size_t) 0, (dvoid **) 0);

/* Initialize handles */
rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_err, OCI_HTYPE_ERROR,
(size_t) 0, (dvoid **) 0);
rc = OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_svc, OCI_HTYPE_SVCCTX,
(size_t) 0, (dvoid **) 0);

/* Connect to database server */
rc = OCILogon(p_env, p_err, &p_svc, "scott", 5, "tiger", 5, "orcl", 4);
//rc = OCILogon(p_env, p_err, &p_svc, "hr/hr@orcl", 10, NULL, -1, NULL, -1);
if (rc != 0) {
OCIErrorGet((dvoid *)p_err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
printf("Error - %.*s/n", 512, errbuf);
exit(8);
}
else
{
printf("Connect to orcl successful! /n");
}

/* Allocate and prepare SQL statement */
rc = OCIHandleAlloc((dvoid *) p_env, (dvoid **) &p_sql,
OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0);

//strcpy(mysql, "insert into employees values('109', 'x12er', 'na', '1888-06-08')");

rc = OCIStmtPrepare(p_sql, p_err, sql,
(ub4) strlen(sql), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT);

/*rc = OCIDefineByPos(p_sql, &p_dfn, p_err, 1, (dvoid *) p_sli,
(sword) 20, SQLT_STR, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT);
rc = OCIDefineByPos(p_sql, &p_dfn, p_err, 2, (dvoid *) p_sli1,
(sword) 20, SQLT_STR, (dvoid *) 0, (ub2 *)0,
(ub2 *)0, OCI_DEFAULT);
*/
/* Execute the SQL statment */
rc = OCIStmtExecute(p_svc, p_sql, p_err, (ub4) 1, (ub4) 0,
(CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT);

if(rc != OCI_SUCCESS && rc != OCI_SUCCESS_WITH_INFO){
printf("insert error!/n");
OCIErrorGet((dvoid *)p_err, (ub4) 1, (text *) NULL, &errcode, errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);
sprintf(out,"insert error message: %s",errbuf);
return 0;
}
else
printf("insert success!/n");
sprintf(out,"insert success!/n");

rc = OCILogoff(p_svc, p_err); /* Disconnect */
rc = OCIHandleFree((dvoid *) p_sql, OCI_HTYPE_STMT); /* Free handles */
rc = OCIHandleFree((dvoid *) p_svc, OCI_HTYPE_SVCCTX);
rc = OCIHandleFree((dvoid *) p_err, OCI_HTYPE_ERROR);

return 1;
}

int oci_query(char *sql, char *out){
/*--- initialize ---*/
OCIDATA data;

int NUM=30;

char USER[31];
char PASS_WORD[31];
char SERVERNAME[31];

// char mysql[] = "select * from employees";

char out1[NUM];//output num 1 column
char out2[NUM];//output num 2 column
char out3[NUM];//output num 3 column
char out4[NUM];
char temp[100];
sword re;//return param

strcpy(USER,"scott");
strcpy(PASS_WORD,"tiger");
strcpy(SERVERNAME,"orcl");

/*--- get data from oracle database ---*/
ociCreatEvnHandle(&data);//initialize handle
ociLogon(&data, USER, PASS_WORD, SERVERNAME);//logon database
ociStmtPrepare(&data, sql);//prepare sql

/*--- bind data from database ---*/
ociDefineByPos(&data, 1, out1, SQLT_CHR);//bind mum 1 column
ociDefineByPos(&data, 2, out2, SQLT_CHR);//bind num 2 column
ociDefineByPos(&data, 3, out3, SQLT_CHR);//bind num 3 column
ociDefineByPos(&data, 4, out4, SQLT_CHR);//bind num 3 column

/*--- initialize output array---*/
memset(out1,0,NUM);
memset(out2,0,NUM);
memset(out3,0,NUM);
memset(out4,0,NUM);

/*--- execute sql ---*/
re = ociStmtExecute(&data);

/*--- output data from database ---*/
while(re != OCI_NO_DATA){
// printf("%s/n", out1);
sprintf(temp,"%s %s %s %s/n", out1, out2, out3,out4);
strcat(out,temp);
memset(temp,0,100);
re = ociStmtFetch(&data);
}

/*--- logout and release handles ---*/
ociHandleFree(&data);
}

myoci.h:

#if !defined( _MYOCIYANGZHI_)
#define _MYOCIYANGZHI_

#include <oci.h>

#define OK 1
#define ERROR 0

/*--- define OCI handle struct---*/
typedef struct{
OCIEnv *p_env;
OCIError *p_err;
OCISvcCtx *p_svc;
OCIStmt *p_sql;
OCIDefine *p_dfn;
OCIBind *p_bnd;
}OCIDATA;

/*--- output error information ---*/
void error_proc(dvoid *errhp, sword status)
{
text errbuf[512];
sb4 errcode;
switch (status)
{
case OCI_SUCCESS:
// printf("OCI_SUCCESS/n");
break;
case OCI_SUCCESS_WITH_INFO:
printf("OCI error: OCI_SUCCESS_WITH_INFO/n");
break;
case OCI_NEED_DATA:
printf("OCI error: OCI_NEED_DATA/n");
break;
case OCI_NO_DATA:
printf("OCI error: OCI_NO_DATA/n");
break;
case OCI_ERROR:
(void)OCIErrorGet((dvoid *)errhp,(ub4)1,NULL,&errcode,
errbuf,(ub4)sizeof(errbuf),OCI_HTYPE_ERROR);
printf("....%d/n.....%s/n",errcode,errbuf);
break;
case OCI_INVALID_HANDLE:
printf("OCI error: OCI_INVALID_HANDLE/n");
break;
case OCI_STILL_EXECUTING:
printf("OCI error: OCI_STILL_EXECUTING/n");
break;
default:
break;
}
}

/*--- create env and initialize OCI handle ---*/
void ociCreatEvnHandle(OCIDATA *data){
sword re;
//......
re = OCIEnvCreate(&(data->p_env),OCI_DEFAULT,(dvoid *)0,
0,0,0,0,(dvoid **)0);
//......
re = OCIHandleAlloc((dvoid *)data->p_env, (dvoid **)&(data->p_err),
OCI_HTYPE_ERROR,0,(dvoid **)0);
if(re != 0)
printf("creation fail!");
error_proc(data->p_err, OCIHandleAlloc((dvoid *)data->p_env,
(dvoid **)&(data->p_svc), OCI_HTYPE_SVCCTX, 0, 0));
}
/*--- logon oracle database ---*/
void ociLogon(OCIDATA *data, char *user, char *pwd, char *servername){
sword status;
status = OCILogon(data->p_env, data->p_err,
&(data->p_svc), user,
(ub4) strlen((char *)user), pwd,
(ub4)strlen((char *)pwd),
servername, (ub4)strlen((char *)servername));
if (status==OCI_SUCCESS)
printf("connection success!/n");
else {
printf("....connect fail!/n");
printf("-----ORA_search,ERROR in OCILogon-----/n");
error_proc(data->p_err,status);
}
}

/*--- prepare sql ---*/
void ociStmtPrepare(OCIDATA *data, char *strSql){
error_proc(data->p_err, OCIHandleAlloc((dvoid *)data->p_env,
(dvoid **)&(data->p_sql), OCI_HTYPE_STMT, 0, 0));
error_proc(data->p_err, OCIStmtPrepare(data->p_sql, data->p_err, strSql,
(ub4) strlen((char *)strSql), (ub4) OCI_NTV_SYNTAX,
(ub4) OCI_DEFAULT));
}

/*--- bind data on array from database ---*/
void ociDefineByPos(OCIDATA *data, int pos, char *out, ub2 type){
error_proc(data->p_err, OCIDefineByPos(data->p_sql, &(data->p_dfn),
data->p_err, pos, (dvoid *) out, (sword)20,
type, (dvoid *) 0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT));

}

/*--- execute sql ---*/
sword ociStmtExecute(OCIDATA *data){
sword status;
if ((status=OCIStmtExecute(data->p_svc, data->p_sql,
data->p_err, (ub4) 0, (ub4) 0,(CONST OCISnapshot *) NULL,
(OCISnapshot *) NULL, OCI_DEFAULT))
&& status != OCI_SUCCESS_WITH_INFO)
{ //.....
error_proc(data->p_err,status);
printf("-----ORA_search,ERROR in OCIStmtExecute-----/n");
return ERROR;
}
return status;
}

/*--- fetch data until output finish ---*/
sword ociStmtFetch(OCIDATA *data){
sword re;
re = OCIStmtFetch(data->p_sql, data->p_err, 1, 0, 0);
return re;
}

/*--- logoff and release handles ---*/
void ociHandleFree(OCIDATA *data){
OCILogoff(data->p_svc, data->p_err);
OCIHandleFree(data->p_sql, OCI_HTYPE_STMT); // Free handles
OCIHandleFree(data->p_svc, OCI_HTYPE_SVCCTX);
OCIHandleFree(data->p_err, OCI_HTYPE_ERROR);
}

#endif

client.c:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/select.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

#define MAXLINE 1024
char sendhead[MAXLINE];

int main(int argc , char* argv[])

{
int sockfd;

struct sockaddr_in servaddr;

char *info="cxt";
int maxfdp1, stdineof;
fd_set rset;
char recvbuf[MAXLINE],tmp[128],sendbuf[MAXLINE];
int n,len,fd;

if(argc!=3){
printf("useage:client address port ");
exit(0);
}

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1 )

{
perror("socket");
exit(1);
}
printf("%s connect server/n",info);

bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(atoi(argv[2]));
inet_pton(AF_INET,argv[1],&servaddr.sin_addr);

if( ( connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) )<0)
{
perror("connect");
exit(1);
}
send(sockfd,info,strlen(info),0);

//FD_ZERO(&rset);
//FD_SET(sockfd, &rset);
//FD_SET(0, &rset);
//maxfdp1=sockfd+1;
for ( ; ; ) {
FD_ZERO(&rset);
FD_SET(sockfd, &rset);
FD_SET(0, &rset);
maxfdp1=sockfd+1;

if( ( select(maxfdp1, &rset, NULL, NULL, NULL) )<=0){
perror("select");
}else{

if (FD_ISSET(0,&rset)){
fgets(sendbuf, MAXLINE, stdin);
n=send(sockfd,sendbuf,strlen(sendbuf)-1,0);
if(n>0)
printf("send: %s",sendbuf);
else
printf("send: %s error,the erro cause is %s:%s/n",sendbuf,errno,strerror(errno));
bzero(sendbuf,strlen(sendbuf));

}

if (FD_ISSET(sockfd, &rset)) { /* socket is readable */
n=recv(sockfd, recvbuf, MAXLINE,0) ;
if(n<0) {
perror("str_cli: server terminated prematurely");
}else if(n==0)
{
printf("sever shutdown!");
exit(-1);
}
//recvbuf
recvbuf
='/0';
printf("receive :%s/n",recvbuf);
fflush(stdout);
bzero(recvbuf,strlen(recvbuf));
}
}
}

exit(0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: