У меня есть DLL, которая перехватывает функцию recv сетевого приложения. Код работает просто отлично (он делает все, что предполагается сделать), но если я добавляю выходные файлы в файл, соединение закрывается через некоторое время работы (приложение на стороне сервера выдает ошибку «Существующее соединение было принудительно закрыто удаленным хозяйничать «).
Это время не всегда одно и то же, иногда оно закрывается почти при инициализации соединения, в других случаях я могу использовать соединение в течение нескольких секунд, прежде чем оно закрывается. Это не дает никаких ошибок или предупреждений. Если я удаляю лог-код, приложение работает нормально. Есть идеи, почему это происходит? Я запускаю его в windows 8 x64
Кроме того, даже стирая код журнала, соединение продолжает закрываться в Windows 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;
}
Я только что нашел проблему и ее решение.
Внедренное приложение настраивало сокеты в неблокирующем режиме. Любая небольшая задержка приводила к выбрасыванию WSAEWOULDBLOCK (код ошибки 10035). Все, что мне нужно было сделать, чтобы это исправить, — это повторить запрос recv, если я получу какую-либо ошибку.
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;
}
}
Других решений пока нет …