2016-12-12 25 views
-6

我的代码有一个很大的问题,我为一个游戏编写代码,从服务器发送数据包到客户端,所有工作都很好,但是问题出在服务器这么大的尺寸上。像100-300这样的更小的尺寸效果很好,但是我的源代码有问题,因为它们有保护来检查数据包的缓冲区,如果很好会阻止发送函数,所以我需要其他函数,我认为还是有很多优化或其他结构..嗯结构大小如此之大,需要优化

这里是问题 - TPacket列表[1000];

typedef struct testa 
{ 
    char t_A[10 + 1]; 
    char t_B[12 + 1]; 
    char t_C[32 + 1]; 
    char t_D[512 + 1]; 
    int  t_E; 
    char t_F[19 + 1]; 
    int  t_G; 
} TPacket; 

typedef struct testb 
{ 
    BYTE header; 
    TPacket list[1000]; // (If i put example 200 etc work) but when is so big = buffer mem_size overflow. memsize(131072) write_pos(32) iSize(598001) 
} Test; 

// FUNCTION TO SEND: 
    Test p; 
    p.header = HEADER_GC_T; 

    SQLMsg *pMsg = DBManager::instance().DirectQuery("SELECT * FROM table.list ORDER BY date DESC LIMIT 1000"); 
    MYSQL_ROW row; 
    int i = 0; 

    if(pMsg->uiSQLErrno != 0) 
     return; 

    while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult))) 
    { 
     p.list[i] = TPacket(); 
     strncpy(p.list[i].t_A, row[1], sizeof(p.list[i].t_A)); 
     strncpy(p.list[i].t_B, row[2], sizeof(p.list[i].t_B)); 
     strncpy(p.list[i].t_C, row[3], sizeof(p.list[i].t_C)); 
     strncpy(p.list[i].t_D, row[4], sizeof(p.list[i].t_D)); 
     str_to_number(p.list[i].t_E, row[5]); 
     strncpy(p.list[i].t_F, row[6], sizeof(p.list[i].t_F) - 1); 
     str_to_number(p.list[i].t_G, row[7]); 
     i++; 
    } 

    if(pMsg->Get()->uiNumRows < 1000) 
    { 
     while (i < 1000) 
     { 
      p.list[i] = TPacket(); 
      strncpy(p.list[i].t_A, "", sizeof(p.list[i].t_A)); 
      strncpy(p.list[i].t_B, "", sizeof(p.list[i].t_B)); 
      strncpy(p.list[i].t_C, "", sizeof(p.list[i].t_C)); 
      strncpy(p.list[i].t_D, "", sizeof(p.list[i].t_D));   
      p.list[i].t_E = 0;   
      strncpy(p.list[i].t_F, "", sizeof(p.list[i].t_F) - 1);   
      p.list[i].t_G = 0;    
      i++; 
     } 
    } 
    ch->GetDesc()->Packet(&p, sizeof(p)); 
+2

听起来像真正的问题是,你需要使用非阻塞发送。 –

+1

你使用C还是C++?如果C++我会建议'std :: string'为cstring和'std :: vector'来替换其他数组。 – NathanOliver

+2

这对您的堆栈很重要。用'std :: vector list(1000);' –

回答

0

Test结构是相当大的,588000个字节,这可能是自动存储过大。使它static应该解决问题,但会使你的代码不可重入,绝对不是线程安全的。

如果问题与最大数据包大小有关,则必须将传输中断为更小的数据包。在结构和SQL SELECT语句中使用较少数量的项目。

strncpy如果它们比目标数组长,则不会终止字符串。你永远不要使用这个功能。阅读你为什么应该stop using strncpy already!。您可以改为使用不同的函数来复制截断,但不会终止目标。

清算环能,可以大大简化,假设默认构造TPacket产生初始化为所有位0。如果没有,只是用memset做一个TPacket。

typedef struct testa { 
    char t_A[10 + 1]; 
    char t_B[12 + 1]; 
    char t_C[32 + 1]; 
    char t_D[512 + 1]; 
    int t_E; 
    char t_F[19 + 1]; 
    int t_G; 
} TPacket; 

typedef struct testb { 
    BYTE header; 
    TPacket list[200]; 
} Test; 

// Utility function: copy with truncation, return source string length 
// truncation occurred if return value >= size argument 
size_t bstrcpy(char *dest, size_t size, const char *src) { 
    size_t i; 
    /* copy the portion that fits */ 
    for (i = 0; i + 1 < size && src[i] != '\0'; i++) { 
     dest[i] = src[i]; 
    } 
    /* null terminate destination if possible */ 
    if (i < size) { 
     dest[i] = '\0'; 
    } 
    /* compute necessary length to allow truncation detection */ 
    while (src[i] != '\0') { 
     i++; 
    } 
    return i; 
} 

// FUNCTION TO SEND: 
void myfunction() { 
    Test p; 
    p.header = HEADER_GC_T; 

    SQLMsg *pMsg = DBManager::instance().DirectQuery("SELECT * FROM table.list ORDER BY date DESC LIMIT 200"); 
    MYSQL_ROW row; 
    int i = 0; 

    if (pMsg->uiSQLErrno != 0) 
     return; 

    while ((row = mysql_fetch_row(pMsg->Get()->pSQLResult))) { 
     p.list[i] = TPacket(); 
     bstrcpy(p.list[i].t_A, sizeof(p.list[i].t_A), row[1]); 
     bstrcpy(p.list[i].t_B, sizeof(p.list[i].t_B), row[2]); 
     bstrcpy(p.list[i].t_C, sizeof(p.list[i].t_C), row[3]); 
     bstrcpy(p.list[i].t_D, sizeof(p.list[i].t_D), row[4]); 
     str_to_number(p.list[i].t_E, row[5]); 
     bstrcpy(p.list[i].t_F, sizeof(p.list[i].t_F), row[6]); 
     str_to_number(p.list[i].t_G, row[7]); 
     i++; 
    } 

    if (i < 1000) { 
     memset(&p.list[i], 0, (1000 - i) * sizeof(p.list[i])); 
     //while (i < 1000) { 
     // p.list[i] = TPacket(); 
     // i++; 
     //} 
    } 
    ch->GetDesc()->Packet(&p, sizeof(p)); 
+0

@ Dr.Vendetta:你为什么不再认为这个答案可以接受? – chqrlie