2013-08-04 3 views
0

У меня есть dll, которая перехватывает функцию recv сетевого приложения. Код работает просто отлично (он делает все, что, по-видимому, делает), но если я добавляю выходные журналы в файл, соединение закрывается через некоторое время работы (приложение на стороне сервера выдает ошибку «Существующее соединение было принудительно закрыто удаленным хозяйничать ").fopen, fprintf и fclose force socket connection end

Это время не всегда одно и то же, иногда оно закрывается почти при инициализации соединения, в другое время я могу использовать соединение за несколько секунд до его закрытия. Он не дает никаких сообщений об ошибке или предупреждении. Если я удалю код журнала, приложение будет работать нормально. Любая идея, почему это происходит? Я запускаю его в окнах 8 x64

Кроме того, даже стирая код журнала, соединение продолжает закрываться в окнах xp x32.

Вот код RECV крюк:

int __stdcall NewRecv(SOCKET socket, char *data, int datalen, int flags) { 
    int result = 0; 
    if(!IsLoginServerPacket(&socket)) { 

     INT size = 0,opcode = 0,temp = 0,writer = 0,second_op = 0; 
     do { 
      size = 0; 
      second_op = 0; 
      temp = 0; 
      writer = 0; 

      while(temp < 2) { 
       temp += recvPacket(socket,recv_gs_buffer+writer,2 - temp,flags); 
       writer += temp; 
      } 

      size = (*(SHORT*)recv_gs_buffer) & 0xffff; 

      // THIS IS THE LOG CODE 
      FILE *f = fopen("debug.txt", "a"); 
      fprintf(f, "datalen=%d, size=%d\n", datalen, size); 
      fclose(f); 

      while(temp < size) { 
       temp += recvPacket(socket,recv_gs_buffer+writer,size - temp,flags); 
       writer += temp; 
      } 

      Decrypt(&gs_crypt,recv_gs_buffer+2,size-2); 
      opcode = (*(recv_gs_buffer+2) & 0xff); 

      if(opcode == EXTENDED_PROTOCOL) { 
       second_op = *(SHORT*)(recv_gs_buffer + 3); 
       second_op &= 0xffff; 
       HandleGameServerPacket(second_op,recv_gs_buffer+2,size-2); 
      } 
     } while(second_op == 0x8a || second_op == 0x8b); 

     if(opcode == 0x00) { 
      SetKey(recv_gs_buffer+4,&gs_crypt); 
      SetKey(recv_gs_buffer+4,&client_crypt); 
     } else 
      Crypt(&client_crypt,recv_gs_buffer+2,size-2); 

     int i = 0; 
     while(i < size) { 
      data[i] = recv_gs_buffer[i]; 
      i++; 
     } 
     //memcpy(data,recv_gs_buffer,size); 
     result = size; 
    } else 
     result = recvPacket(socket,data,datalen,flags); 

    return result; 
} 
+0

Одна вещь, я замечаю, что вы передаете в datalen, но тогда вы пишите 'data [i]' используя 'size' в качестве длины блока, которая установлена ​​в 0xffff. – Devolus

+0

Да, но параметр datalen всегда имеет значение 16384, а самый большой пакет, отправленный сервером, не превышает 300 байт, поэтому он не должен переполняться, я думаю. – Nadir

+0

Возможно ли, что просто открытие файла, запись на него и закрытие его вызывает достаточно задержки (возможно, иногда?), Чтобы заставить приложение думать, что что-то не так (или заставить пакеты удаляться, что, в свою очередь, вызывает приложение было «недовольным»? Пробовали ли вы просто открыть файл в начале дня, а затем писать без закрытия файла (или уменьшить количество файлов плиток открыто/закрыто)? –

ответ

0

Я просто нашел эту проблему и ее решение.

Введенное приложение настраивало сокеты в режиме без блокировки. Любая небольшая задержка заключалась в том, что он бросал WSAEWOULDBLOCK (код ошибки 10035). Все, что я должен был сделать, чтобы исправить это было повторить запрос ПРИЕМ, если я получить какую-либо ошибку

INT val = 0; 
while(temp < 2) { 
    val = recvPacket(socket,recv_gs_buffer+writer,2 - temp,flags); 
    if(val > 0) { 
     temp += val; 
       writer += temp; 
    } 
} 

И

val = 0; 
while(temp < size) { 
    val = recvPacket(socket,recv_gs_buffer+writer,size - temp,flags); 
    if(val > 0) { 
     temp += val; 
       writer += temp; 
    } 
} 
Смежные вопросы