纯C语言实现通过ODBC把数据写入数据库,写到第7次的时候写不进去,请问下是什么原因

时间:2021-08-07 23:36:03
// 整个项目(纯C代码实现)是通过客户端发送数据到服务器
//然后服务器把数据接收再通过ODBC  保存到数据库
//数据库是Sql server 2008 R2       
//出现的问题: 在第7段数据存入数据库时 出现客户端无法连接到服务器的情况    (每1段里面包含10条数据,每次写1条数据进数据库)

例如:0146c0a8013220160325142536a2000a90eb001e0000003e1b1603211151417590e5001e000000401b1603211151521690e0001e000000421b1603211152054590dc0014000000441b1603211152146490d80014000000461b1603211152215790d3001e000000481b1603211152295090d10014000000491b1603211152344490cf00140000004a1b1603211152395490c500140000004f1b1603211153016290c30014000000501b1603211153057f                  为1段数据


a104000a000000d51416030413525866    为1条数据


 一、首先我自己的处理方法是: 整个项目注释掉写入数据库这一部分,   结果: 服务器与数据库都能正常运行,超过 7段也能成功,上百段也成功
 二、我把客户端发送的数据 调到只有 6段,结果: 6段数据完整成功写入数据库
 三、我把客户端发送的数据 调到只有 4段,    结果: 4段数据成功写入数据库
 四、我把客户端发送的数据 调到只有 2段,    结果: 2段数据成功写入数据库
 五、我把客户端发送的数据 调到有10段,  结果: 只有6段数据成功写入数据库,其他的没有写入
 六、我把客户端发送的数据 调到有20段,  结果: 只有6段数据成功写入数据库,其他的没有写入
 七、我把客户端发送的数据 调到有50段,  结果: 只有6段数据成功写入数据库,其他的没有写入




//下面是写1条数据进数据库代码
  SQLRETURN retcode; 
  SQLHENV henv;      // 环境句柄
  SQLHDBC hdbc1;    //连接句柄
  SQLHSTMT hstmt1;

            //1.环境句柄  
  retcode   =   SQLAllocHandle(SQL_HANDLE_ENV,NULL,&henv);   //申请环境句柄
  retcode   =   SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(SQLPOINTER)SQL_OV_ODBC3,SQL_IS_INTEGER); //设置环境属性    
  //2.连接句柄    
  retcode   =   SQLAllocHandle(SQL_HANDLE_DBC,henv,&hdbc1);     
//申请数据库连接句柄
  retcode   =   SQLConnect(hdbc1,(SQLCHAR*)"csql",SQL_NTS,(SQLCHAR*)"sa",SQL_NTS,(SQLCHAR*)"qs87519830@",SQL_NTS);
  //判断连接是否成功  
  if((retcode == SQL_SUCCESS)||(retcode == SQL_SUCCESS_WITH_INFO))  
  {       
     retcode   =   SQLAllocHandle(SQL_HANDLE_STMT,hdbc1,&hstmt1);   // 申请sql语句句柄
     QLCHAR sql[]="insert into yf values (?,?,?,?,?);";
     QLINTEGER P = SQL_NTS; 
     retcode =   QLPrepare(hstmt1,sql,SQL_NTS);    //直接执行SQL语句
     retcode =   QLBindParameter(hstmt1,1,SQL_PARAM_INPUT,SQL_C_DOUBLE,SQL_INTEGER,0,2,&Dremain,0,&P); //Dremain 表示消费前金额
     retcode =   QLBindParameter(hstmt1,2,SQL_PARAM_INPUT,SQL_C_DOUBLE,SQL_INTEGER,0,3,&Fconsume,0,&P); //Fconsume表消费金额
     retcode =   QLBindParameter(hstmt1,3,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,10,0,card_num,10,&P); //card1 卡号
     retcode =   QLBindParameter(hstmt1,4,SQL_PARAM_INPUT,SQL_C_LONG,SQL_INTEGER,0,0,&water_num,,0,&P); //water 流水号
     retcode =   QLBindParameter(hstmt1,5,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,30,0,str_data,30,&P);//str_data5 日期
     retcode =   QLExecute(hstmt1);
     if(retcode==SQL_SUCCESS || retcode==SQL_SUCCESS_WITH_INFO)
     {
     QLFreeHandle (SQL_HANDLE_STMT, hstmt1);  //释放语句句柄   1
     }else printf("添加数据库操作失败!\n"); 
     QLDisconnect(hdbc1);        //断开与数据库的连接   2
  }   
  else printf("连接数据库失败!\n");
  SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);     //释放连接句柄   3
  SQLFreeHandle(SQL_HANDLE_ENV, henv);      //释放环境句柄   4

下面第一张为服务器 图片,第二张为客户端 图片,

纯C语言实现通过ODBC把数据写入数据库,写到第7次的时候写不进去,请问下是什么原因纯C语言实现通过ODBC把数据写入数据库,写到第7次的时候写不进去,请问下是什么原因

12 个解决方案

#1


有没有大神来回复我一下啊,, 纯C语言实现通过ODBC把数据写入数据库,写到第7次的时候写不进去,请问下是什么原因

#2


如果不能调试程序,就输出日志来判断哪里出问题,别靠猜

#3


我用errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
这是什么原因啊@xdashewan

#4


这里应该没有C大神,至少我不是,看起代码费尽...
推测吧,给点测试建议:
第一,最像某些连接数超限制:这个连接数可能是:sql(默认3万多...),odbc(默认100吧?),网络(我不知道...),你程序中用的中间控件限制,你某些变量长度。。。还有就是释放是否成功?也不知道。
第二,你第7段会不会有特殊字符,把它拿到第2段去,试试,是不是第2段就失败?
第三,连接网络服务器失败?这个报错是系统抛的?还是,你过滤了自己写的,如果被catch了,最好抛出原始错误信息看看。

#5


@spiritofdragon
你说的第一点我用小段数据处理试过了,不会超过限制数的,  十段 数据,每段1条,最多就100条,客户端也只发到第61 条就发不过去了,也就是第7段发不过去,也就70 不会超过限制数的, 释放怎么判断是否成功?sql的释放上面代码有, socket的释放 我用的closesocket(slisten);函数,closesocket(sClient); WSACleanup(); 怎么判断是否成功释放?
第二点第7段不存在特殊字符,因为我是3段数据循环的, 第7段数据和第1段是一模一样的,
第三点 系统connect函数自带errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
现在我是从系统给我的报错提示知道  客户端的连线要求被服务器端拒绝, 然后怎么改服务器呢?为什么服务器会拒绝客户端呢?
求大神指教,感激涕零,,

#6


引用 5 楼 fyf350232349 的回复:
@spiritofdragon
你说的第一点我用小段数据处理试过了,不会超过限制数的,  十段 数据,每段1条,最多就100条,客户端也只发到第61 条就发不过去了,也就是第7段发不过去,也就70 不会超过限制数的, 释放怎么判断是否成功?sql的释放上面代码有, socket的释放 我用的closesocket(slisten);函数,closesocket(sClient); WSACleanup(); 怎么判断是否成功释放?
第二点第7段不存在特殊字符,因为我是3段数据循环的, 第7段数据和第1段是一模一样的,
第三点 系统connect函数自带errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
现在我是从系统给我的报错提示知道  客户端的连线要求被服务器端拒绝, 然后怎么改服务器呢?为什么服务器会拒绝客户端呢?
求大神指教,感激涕零,,


按照这个分析,似乎问题不是数据库的,而是你的服务器端的代码有问题了是吧

#7


嗯嗯,而且我刚才注释掉服务器 ,直接写进数据库 超过 7段也能写进去,说明不是写进数据库的问题了,

#8


服务器代码贴上
     //初始化WSA
     WORD sockVersion = MAKEWORD(2,2);
     WSADATA wsaData;
     if(WSAStartup(sockVersion, &wsaData)!=0)
     {
         return 0;
     }
     struct hostent *host;
     host=gethostbyname("192.168.1.102");
     //创建套接字
     SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if(slisten == INVALID_SOCKET)
     {
         printf("socket error !");
         return 0;
     }
     //绑定IP和端口
     sockaddr_in sin;
     sin.sin_family = AF_INET;
     sin.sin_port = htons(5000);
     sin.sin_addr.S_un.S_addr = INADDR_ANY;
     if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
     {
         printf("bind error !");
     }

     //开始监听
     if(listen(slisten, 5) == SOCKET_ERROR)
     {
         printf("listen error !");
         return 0;
     }
 
     //循环接收数据
     SOCKET sClient;
     sockaddr_in remoteAddr;
     int nAddrlen = sizeof(remoteAddr);
     char revBuf[6000]={0}; 
 int rs = 1,times=1;
     while (rs)
     {
         printf("等待连接...\n");
         sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
         if(sClient == INVALID_SOCKET)
         {
             printf("accept error !");
             continue;
         }
         printf("接受到一个客户端的连接,ip地址为:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
         //接收数据
         int ret = recv(sClient, revBuf, sizeof(revBuf), 0);  
 char *revData = (char *)malloc(12000);   //动态分配内存
 strncpy(revData,revBuf,sizeof(revBuf));
 ZeroMemory(revBuf, sizeof(revBuf));   //清空缓冲区
         if(ret > 0)
         {
             revData[ret] ='\0';
             printf("数据:%s\n",revData);
         }
Split_Client_data(revData,ret);      // 提取数据 

#9


情况就是 客户端发数据给服务器 成功,
单独写进数据库  也成功,
 拼凑起来,客户端发数据给服务器,然后服务器写进数据库,只能写 6段,第7段显示客户端连接不上服务器,,不成功

#10


会不会是连接池一下子用完了呢, 有没有关闭连接

#11


@tcmakebest
你看我的代码啊,ODBC 是按顺序关闭的,服务器的套接字也是关闭了         closesocket(sClient); closesocket(slisten);
    WSACleanup();

#12


listen(slisten, 5) 这个5调大些看是不是与它有关, 楼主的服务端处理过程没有开线程,那处理数据的时候是不能接收客户端连接了,而这个5是在排队的客户端数量,加上正在处理的1个,好像正好是6个.

#1


有没有大神来回复我一下啊,, 纯C语言实现通过ODBC把数据写入数据库,写到第7次的时候写不进去,请问下是什么原因

#2


如果不能调试程序,就输出日志来判断哪里出问题,别靠猜

#3


我用errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
这是什么原因啊@xdashewan

#4


这里应该没有C大神,至少我不是,看起代码费尽...
推测吧,给点测试建议:
第一,最像某些连接数超限制:这个连接数可能是:sql(默认3万多...),odbc(默认100吧?),网络(我不知道...),你程序中用的中间控件限制,你某些变量长度。。。还有就是释放是否成功?也不知道。
第二,你第7段会不会有特殊字符,把它拿到第2段去,试试,是不是第2段就失败?
第三,连接网络服务器失败?这个报错是系统抛的?还是,你过滤了自己写的,如果被catch了,最好抛出原始错误信息看看。

#5


@spiritofdragon
你说的第一点我用小段数据处理试过了,不会超过限制数的,  十段 数据,每段1条,最多就100条,客户端也只发到第61 条就发不过去了,也就是第7段发不过去,也就70 不会超过限制数的, 释放怎么判断是否成功?sql的释放上面代码有, socket的释放 我用的closesocket(slisten);函数,closesocket(sClient); WSACleanup(); 怎么判断是否成功释放?
第二点第7段不存在特殊字符,因为我是3段数据循环的, 第7段数据和第1段是一模一样的,
第三点 系统connect函数自带errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
现在我是从系统给我的报错提示知道  客户端的连线要求被服务器端拒绝, 然后怎么改服务器呢?为什么服务器会拒绝客户端呢?
求大神指教,感激涕零,,

#6


引用 5 楼 fyf350232349 的回复:
@spiritofdragon
你说的第一点我用小段数据处理试过了,不会超过限制数的,  十段 数据,每段1条,最多就100条,客户端也只发到第61 条就发不过去了,也就是第7段发不过去,也就70 不会超过限制数的, 释放怎么判断是否成功?sql的释放上面代码有, socket的释放 我用的closesocket(slisten);函数,closesocket(sClient); WSACleanup(); 怎么判断是否成功释放?
第二点第7段不存在特殊字符,因为我是3段数据循环的, 第7段数据和第1段是一模一样的,
第三点 系统connect函数自带errno 打印出来,显示                    ECONNREFUSED 连线要求被server端拒绝。
现在我是从系统给我的报错提示知道  客户端的连线要求被服务器端拒绝, 然后怎么改服务器呢?为什么服务器会拒绝客户端呢?
求大神指教,感激涕零,,


按照这个分析,似乎问题不是数据库的,而是你的服务器端的代码有问题了是吧

#7


嗯嗯,而且我刚才注释掉服务器 ,直接写进数据库 超过 7段也能写进去,说明不是写进数据库的问题了,

#8


服务器代码贴上
     //初始化WSA
     WORD sockVersion = MAKEWORD(2,2);
     WSADATA wsaData;
     if(WSAStartup(sockVersion, &wsaData)!=0)
     {
         return 0;
     }
     struct hostent *host;
     host=gethostbyname("192.168.1.102");
     //创建套接字
     SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if(slisten == INVALID_SOCKET)
     {
         printf("socket error !");
         return 0;
     }
     //绑定IP和端口
     sockaddr_in sin;
     sin.sin_family = AF_INET;
     sin.sin_port = htons(5000);
     sin.sin_addr.S_un.S_addr = INADDR_ANY;
     if(bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
     {
         printf("bind error !");
     }

     //开始监听
     if(listen(slisten, 5) == SOCKET_ERROR)
     {
         printf("listen error !");
         return 0;
     }
 
     //循环接收数据
     SOCKET sClient;
     sockaddr_in remoteAddr;
     int nAddrlen = sizeof(remoteAddr);
     char revBuf[6000]={0}; 
 int rs = 1,times=1;
     while (rs)
     {
         printf("等待连接...\n");
         sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
         if(sClient == INVALID_SOCKET)
         {
             printf("accept error !");
             continue;
         }
         printf("接受到一个客户端的连接,ip地址为:%s \r\n", inet_ntoa(remoteAddr.sin_addr));
         //接收数据
         int ret = recv(sClient, revBuf, sizeof(revBuf), 0);  
 char *revData = (char *)malloc(12000);   //动态分配内存
 strncpy(revData,revBuf,sizeof(revBuf));
 ZeroMemory(revBuf, sizeof(revBuf));   //清空缓冲区
         if(ret > 0)
         {
             revData[ret] ='\0';
             printf("数据:%s\n",revData);
         }
Split_Client_data(revData,ret);      // 提取数据 

#9


情况就是 客户端发数据给服务器 成功,
单独写进数据库  也成功,
 拼凑起来,客户端发数据给服务器,然后服务器写进数据库,只能写 6段,第7段显示客户端连接不上服务器,,不成功

#10


会不会是连接池一下子用完了呢, 有没有关闭连接

#11


@tcmakebest
你看我的代码啊,ODBC 是按顺序关闭的,服务器的套接字也是关闭了         closesocket(sClient); closesocket(slisten);
    WSACleanup();

#12


listen(slisten, 5) 这个5调大些看是不是与它有关, 楼主的服务端处理过程没有开线程,那处理数据的时候是不能接收客户端连接了,而这个5是在排队的客户端数量,加上正在处理的1个,好像正好是6个.