现在的位置: 首页 > 综合 > 正文

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

2013年12月01日 ⁄ 综合 ⁄ 共 15193字 ⁄ 字号 评论关闭

这就是我两个星期的成果

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[n]='/0';
                        printf("receive :%s/n",recvbuf);
                        fflush(stdout);
                        bzero(recvbuf,strlen(recvbuf));
                }
                }
        }

       exit(0);
}

抱歉!评论已关闭.