String => Char или др.способом [Delphi]

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by ALeXX&7, 26 Feb 2011.

  1. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Всем доброго времени суток! Бьюсь об стол уже часа 1,5...
    Нужно передать строку от сервера клиенту...
    Code:
    ...
    st:= 'Privet'; // тип string
    ...
    Buf:= st[1]; // тип char 
    ... 
    send(FSocket,Buf,1,0);
    
    В результате, как видно, передастся только 1-ый символ 'Р'... Как передать всю строку целиком??. Пробывал через Pchar (т.е. Buf: PChar), выдает краказябры...
    Спасибо за любую помощь!
     
  2. arnis

    arnis Member

    Joined:
    30 Jan 2011
    Messages:
    280
    Likes Received:
    23
    Reputations:
    0
    Правильно что передает 1 символ так как Тип Char простой тип переменной, используемый для хранения простого символа.
     
  3. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Это мне ясно... Поэтому и интересуют какими методами можно передать всю строку...??
     
  4. arnis

    arnis Member

    Joined:
    30 Jan 2011
    Messages:
    280
    Likes Received:
    23
    Reputations:
    0
    Дайте описание на функцию send
     
  5. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    send - отправка данных клиенту...
    Строкой пробовал тож не катит ...
    В нете выискивал..., натыкался что вторым параметром должен быть тип Char ( или pchar),
    т.е. send(socket, char, nil)
     
  6. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Code:
    send(FSocket, st[1], Length(st), 0);
     
  7. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Уже по-всякому перепробывал, никак(...
     
  8. arnis

    arnis Member

    Joined:
    30 Jan 2011
    Messages:
    280
    Likes Received:
    23
    Reputations:
    0
    Описание на функцию дайте тогда что решить можно. А так черт знает какую функцию и из какого модуля вы используете.
     
  9. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Грубо говоря:

    send - отправка в буфер исходящих (сервер отправляет клиенту)
    recv - изъятие из входящих (клиент получает от сервера)

    т.е. если у сервера send(1,2,3,4), то у клиента те же параметры только ф-ия recv(1,2,3,4)
     
  10. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    1. Какая версия дельфи? Это важно потому что в версиях >= 2009 Char 2 байта соотвественно string из 5 символов будет занимать 10 байт. А в эту функцию передается длина буфера в байтах. Либо объявлять str: AnsiString;
    2. Почему упорно передаешь длину буфера 1? сколько передаешь столько и читает то есть один байт. Опять же для более ранних версий следует передавать длину Length(str) для поздних Length(str) * 2. В общем случае всегда правильно передавать Length(str) * SizeOf(Char)

    В общем в зависимости от версии дельфи надо смотреть, возможно что и AnsiString или PAnsiChar надо юзать

    Второй параметр объявлен как-то так:
    var buf;
    Ну что, тебе это сильно помогло?
     
  11. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    7-ая версия
     
  12. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Пробывал через length(str) вообще ничего не выводит, но и ошибок нет...

    Сервер:
    Code:
    Buf:= 'Privet';
    strlen:= Length(Buf);
    send(FSocket,Buf[1],strlen,0);
    
    Клиент:
    Code:
    strlen:= Length(Buf);  
    recv(ClientSocket,Buf[1],strlen,0);  
    label1.Caption:= Buf;   
     
  13. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Это из за особенностей string'a, str[1] передает только символ
    send(Fsocket, PChar(@str[1])^, Length(s) * SizeOf(Char), 0);

    100% рабочий вариант вызова

    щас еще насчет правильного приема подумаю
     
  14. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    str: string;
    ................
    SetLength(str, buflen);
    recv(FSocket, PChar(@s[1])^, buflen, 0);
     
  15. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    У меня самый обычный вариант
    Code:
    send(FSocket, st[1], Length(st), 0);
    работает. Проверил у себя на примере работы с HTTP сервером.

    К сожалению, это не так.
    На клиенте должно быть не так:
    А как то так:
    Code:
    recv(ClientSocket, Buf[1], 1024, 0);  
    Label1.Caption := Buf;
    Перед этим нужно также задать размер буффера Buf. Это может быть массив фиксированой длины, например. Тогда вместо 1024 нужно будет написать другое число.

    Выложи полный код, посмотрим.
     
    #15 Chrome~, 26 Feb 2011
    Last edited: 26 Feb 2011
  16. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Интересная ситуация.
    Мне было лень подключать сокеты, и я проверял на потоках (stream)
    Методы
    Write(const Buffer; Count: Longint)
    Read(var Buffer; Count: Longint)
    имеют похожее объявление - нетипизированный буфер и длина буфера, и я предположил что чтение/запись имеют схожий механизм с сокетами. И вариант str[1] там не прокатил.
     
  17. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    GhostOnline, попробуй у себя такой код (Delphi 7):
    Code:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      FileStream: TFileStream;
      Str: String;
    begin
      FileStream := TFileStream.Create('C:\TestFile_52386.txt', fmCreate);
    
      Str := 'Test string';
      FileStream.Write(Str[1], Length(Str));
    
      FileStream.Free;
    end;
    В "C:\TestFile_52386.txt" должен создаться текстовый файл из указанным в коде текстом.
     
    1 person likes this.
  18. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Может что т недопонял я, но всё равн не хочет...
    Переделал под себя:

    Code:
    Buf: string;
    ..............
    strlen:= Length(Buf);
    SetLength(buf, strlen);   
    recv(ClientSocket,PChar(@buf[1])^, strlen,0);
    label1.Caption:= Buf;
     
  19. Chrome~

    Chrome~ Elder - Старейшина

    Joined:
    13 Dec 2008
    Messages:
    936
    Likes Received:
    162
    Reputations:
    27
    Чувак ты все делаешь неправильно...
    В strlen должен быть размер буффера, который задаешь ты сам. А не различные Length и т. д.
    В самом начале Buf равняеться пустой строке, значит функция Length вернет 0.
     
    #19 Chrome~, 26 Feb 2011
    Last edited: 26 Feb 2011
  20. ALeXX&7

    ALeXX&7 New Member

    Joined:
    4 Oct 2010
    Messages:
    50
    Likes Received:
    1
    Reputations:
    0
    Подставлял шестерку - аналогично...