用c和mysql API写的简易操作mysql数据库的多线程服务器和客户端代码

此程序通过mysql API函数管理mysql数据库模仿远程管理mysql数据库,错误之处,还请指教!

 服务器端:

 /*gcc command: gcc -o mypthread_server mypthread_server.c query_api.c $(mysql_config --libs) $(mysql_config --cflags) -pthread*/
#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 1024

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);

                int i;
                /*for (i = 0; i < num ; i++) {
                        sendbuf[i] = recvbuf[num - i -1];
                        //sendbuf[i] = recvbuf[i];
                }*/

                i=query(recvbuf,sendbuf);
                if(i<0){
                        sprintf(sendbuf,"query 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);
}


 

query_api.c:

 

 

#include   <stdio.h>  
#include   <stdlib.h>  
#include   <mysql/mysql.h> 
#include   <string.h>


int query(char *command, char *buf) {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;

char *server = "localhost";
char *user = "cxt";
char *password = "cxt"; /* �˴��ij��������� */
char *database = "mysql";

conn = mysql_init(NULL);

/* Connect to database */
if (!mysql_real_connect(conn, server,
user, password, database, 0, NULL, 0)) {
fprintf(stderr, "%s/n", mysql_error(conn));
return -1;
}
int i,num_rows,num_fields;
char  out[128]="";
char  temp[128];

/* send SQL query */
if (mysql_query(conn, command)) {
        fprintf(stderr, "�%s/n", mysql_error(conn));
        return -1;
}
else{
        res = mysql_use_result(conn);
    if (res)  // there are rows
    {
        num_fields = mysql_num_fields(res);
        while ((row = mysql_fetch_row(res)) != NULL){
                for(i=0;i<num_fields;i++){
                        sprintf(temp,"%s /t",row[i]);
                        strcat(out,temp);
                        bzero(temp,sizeof(temp));
        }
        sprintf(out,"%s /n",out);
        strcat(buf,out);
        bzero(out,sizeof(out));
        }
        // retrieve rows, then call mysql_free_result(result)
    }
    else  // mysql_store_result() returned nothing; should it have?
    {
        if (mysql_errno(conn))
        {
                fprintf(stderr, "Error: %s/n", mysql_error(conn));
                return -1;
        }
        else if (mysql_field_count(conn) == 0)
        {
            // query does not return data
            // (it was not a SELECT)
                num_rows = mysql_affected_rows(conn);
                sprintf(buf,"Query success! %d row is effected!/n",num_rows);
        }
    }
}


/* close connection */
mysql_free_result(res);
mysql_close(conn);
return 0;
}

 

 

客户端:

#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);
}

 

 

 

你可能感兴趣的:(用c和mysql API写的简易操作mysql数据库的多线程服务器和客户端代码)