Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.05.2012, 14:30   #11
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Покажи код, где ты принимаешь строки.
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 19.05.2012, 17:38   #12
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию 1 пост

Так вроде все написал в 1 посте ! Или что то ещё ?
fucil вне форума Ответить с цитированием
Старый 19.05.2012, 18:38   #13
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Функции recv() что-то не видно, где принимаете данные из сокета?
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 19.05.2012, 22:43   #14
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию Да прости это я невнимателен

В потоке Connect ! И соответственно прием данных и передача на ReceiveData(Socket: TSocket; Buffer: PByte);
Код:
procedure Connect;
var
  Buffer: Array[0..8192] Of Char;
  iRecv: Integer;
Begin
  if (WSAStartup($0202, wsaData) <> 0) then
  begin
    Exit;
  end;
  Close1 := False;
  repeat
    //Prepare a listen socket to be used for our connection and declare its host/port information
    hSocket := Socket(AF_INET, SOCK_STREAM, 0);
    Addr.sin_family   := AF_INET;
    Addr.sin_port     := htons(hPort);
    Addr.sin_addr.S_addr := INET_ADDR(PChar(FrmMain.GetIPFromHost(hHost)));
    //Attempt the connection using our socket
    if (Winsock.Connect(hSocket, Addr, SizeOf(Addr)) = 0) then
    begin
      //Notify our connected client of the connection and send our information
      //Attempt to receive data from our socket.
      ZeroMemory(@Buffer, SizeOf(Buffer));
      iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
      while ((iRecv > 0) and (iRecv <> INVALID_SOCKET)) do
      begin
        FrmMain.ReceiveData(hSocket, @Buffer);
        ZeroMemory(@Buffer, SizeOf(Buffer));
        iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
      end;
      //We got disconnected if we reach this point
      CloseSocket(hSocket);   
    end;
    //Wait 3 seconds and repeat our connection attempt
    Sleep(3000);
   until (Close1);
  WSACleanup();
end;

Последний раз редактировалось fucil; 19.05.2012 в 22:54.
fucil вне форума Ответить с цитированием
Старый 19.05.2012, 23:09   #15
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

имхо, у вас типичная ошибка. Вы считаете, что клиент всегда получит данные теми же порциями, какими они были отправлены с сервера. Это не так. TCP -- это поток данных, на клиент они могут попасть любыми порциями.

Например, сервер отправляет строку "POST|Тут много данных" одной порцией. На клиент это может прийти в виде 3-х пакетов (понадобится 3 вызова recv() ):
1) "POS"
2) "T|Тут мн"
3) "ого данных"

Пример утрированный, но при больших объёмах так оно и работает. Т.е. клиент должен собрать все данные, а потом уже их разбирать. Ну или не все, но хотя бы понимать, в какой позиции потока данных он находится. У вас же ReceiveData() каждый раз начинает жизнь "с нуля".

> что приходят не все строки, не всегда но очень часто (пропадают, недожодят)!

TCP не теряет ни одного переданного бита. Максимум, что может потеряться, это соединение
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 19.05.2012 в 23:30.
veniside вне форума Ответить с цитированием
Старый 19.05.2012, 23:31   #16
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Посмотри внимательно сишный пример из МСДНа:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
При создании сокета 3м параметром указывай IPPROTO_TCP вместо нуля.
И может быть следует переписать кусок кода так:
Код:
  str:='';//строка
  iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
  while (iRecv > 0) do
  begin
    str:=str+Copy(Buffer,1,iRecv);        
    iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
  end;
  FrmMain.ReceiveData(hSocket, @str);
Применять ZeroMemory() смысла нет, все равно recv() возвращает размер пришедшего пакета, который и запишется с первого символа в твоем массиве Buffer. Функцией Copy() выдираешь из него пришедшие данные и дополняешь финальную строку. И так, пока не произойдет ошибка сокета.
"ковыряю изнутри" (с)

Последний раз редактировалось 3D Hunter; 19.05.2012 в 23:36.
3D Hunter вне форума Ответить с цитированием
Старый 20.05.2012, 00:15   #17
fucil
Форумчанин
 
Регистрация: 24.02.2010
Сообщений: 148
По умолчанию ??

По поводу veniside У вас же ReceiveData() каждый раз начинает жизнь "с нуля".
Да но такой же метод и на сервере, и все гуд: как часы (
А вот как посоветовал 3D Hunter пробовал, так у меня вообще ничего не приходит тогда.

Я тут вот что подумал, так как у tcp данные не теряются, а только подключение, то может все таки у меня просто большой слип, перед переподкл ???
Код:
procedure Connect;
var
  Buffer: Array[0..8192] Of Char;
  iRecv: Integer;
  str:string;
Begin
  if (WSAStartup($0202, wsaData) <> 0) then
  begin
    Exit;
  end;
  Close1 := False;
  repeat
    hSocket := Socket(pF_INET, SOCK_STREAM, IPPROTO_TCP);
    Addr.sin_family   := pF_INET;
    Addr.sin_port     := htons(hPort);
    Addr.sin_addr.S_addr := INET_ADDR(PChar(FrmMain.GetIPFromHost(hHost)));
    if (Winsock.Connect(hSocket, Addr, SizeOf(Addr)) = 0) then
    begin
      ZeroMemory(@Buffer, SizeOf(Buffer));
      iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
      while ((iRecv > 0) and (iRecv <> INVALID_SOCKET)) do
      begin
        FrmMain.ReceiveData(hSocket, @Buffer);
        ZeroMemory(@Buffer, SizeOf(Buffer));
        iRecv := Recv(hSocket, Buffer, SizeOf(Buffer), 0);
      end;
      CloseSocket(hSocket);
    end;
	Sleep(3000); /// может его вообще убрать ! я убрал вроде все гуд пока но потери данных пока проверить немогу !
   until (Close1);
  WSACleanup();
end;

Последний раз редактировалось fucil; 20.05.2012 в 00:24.
fucil вне форума Ответить с цитированием
Старый 20.05.2012, 00:44   #18
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

вам посоветовали правильную вещь -- собирать все данные, перед их парсингом. А вы продолжаете какие-то слипы менять. В вашей программе вобще не нужны Sleep(), у вас send() и recv() блокирующие, а значит, они сами разберутся, сколько им ждать.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поменять все строки местами inessam Microsoft Office Excel 8 14.04.2011 10:15
Выбрать все числа из строки Jene4ka Общие вопросы Delphi 7 17.03.2011 07:13
Даны строки S и S0. Удалить из строки S все подстроки, совпадающие с S0 . Если совпадающих подстрок нет, Шпунюся Помощь студентам 1 16.12.2010 21:02
Из строки удалить все цифры. Shnurik_sh Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 24.11.2010 01:17
Удалит все строки! sanek_next Помощь студентам 0 11.10.2010 21:10