2012-01-19 4 views
2

Это попытка перефразировать my previous question в результате полученной ими обратной связи.Ищу (бесплатно) рамки для сетевого программирования

Я хочу простую сетевую связь, которую я могу использовать в качестве базовой структуры и никогда не смотреть снова. Я просто хочу, чтобы вы нажимали строку с одного ПК на другой и получали строку в ответ. Я не хочу, чтобы беспокоиться об открытии разных цветов, держа их открытыми, открытие их, если они закрываются, и т.д.

я хочу сконцентрироваться на применении и имею простой функциональный API вдоль линий:

SendStringToOtherPc() : String; // Called at PC#1. 
            // Returns PC#2's result string 
            // or "" on error (or throws exception) 
ProcessReceivedStringAndReply(); // Called at PC# 2. Sends result string 
  • Мне нужно знать, ответил ли другой компьютер или нет; и если да, то какая строка результата была
  • также «приятно иметь» было бы для обоих ПК инициировать связь. Если нет, у меня может быть один из них (опрос клиентов) или другой отправить его сообщение в ответ на пульс, который мне нужно добавить.

Я полагаю, что те, с несколькими fprojects под их поясами имеют каркас «стартер», который они используют для каждого нового проекта, просто добавив для конкретного применения журнала - и это такая framwork, или уровень абстракции, что я хочу , Может ли кто-нибудь указать мне URL?

Я ничего не знаю о программировании сокетов и на самом деле не успеваю учиться. Если я это сделаю, пострадает какой-то другой проект.

Несмотря на то, что я уважаю аргумент, что я должен понимать, что делает мое программное обеспечение, есть веские аргументы в пользу того, что каждому не нужно будет разрабатывать это конкретное колесо для себя, и, безусловно, есть какая-то FOSS, вокруг которой что-то делает Я хочу?

Заранее спасибо.


Обновление: Я, кажется, начал немного противоречий, с некоторыми считая меня ленивым или обречена на катастрофу. Поэтому, может быть, я должен немного объяснить свою историю.

Я потратил три десятилетия на развитие телекоммуникационного программного обеспечения, и мы всегда следовали за OSI 7 layer model. Обычно я был слоем 3, сетевым уровнем, и независимо от того, была ли это телефонной станцией, базовой станцией или hanset, был ли протокол ISDN, ISUP, DECT, GSM, GPRS, UMTS или спутниковым протоколом, я всегда мог точка доступа Serveice уровня 2, уровень переноса данных, «эй, вы! Получите это сообщение другому человеку и скажите мне, что его ответ». Знал ли я, как это было сделано? Меня это волнует?

@CosmicPrund, которому, вероятно, будет присужден ответ, если кто-то не укажет меня на уровне 2, сказал: «Истинный ответ на этот вопрос заключается в том, что все, что вам нужно, это узнать, как использовать Indy», и я прошу не согласиться.

Кто-то будет, но не я, если я могу ему помочь. Я уже склонялся к слишком многим навыкам, языкам программирования, системам баз данных, системам отпечатков и всегда избегал изучения большего, чем обзор другого, если можно. Как и сэр Исаак Ньютон, я предпочел бы стоять на плечах гигантов.

Программное обеспечение просто становится слишком большим для одного парня. Неужели никто из вас не запускает каждый проект с нуля? Я думаю, вы повторно используете сетевой код из предыдущего проекта (?), И этот многоразовый код является моим «Слоем 2». И мой вопрос в том, где я могу загрузить такой код и использовать его, не понимая его внутренней работы?

Кто-нибудь знает о такой вещи?


Ответ: Я использовал Инди и получил то, что хотел. Я попытаюсь создать библиотеку функций, которые я могу использовать в качестве уровня сетевой абстракции.

+2

Вы не можете избежать проблем с подключением, отключением, задержкой и всеми другими проблемами, связанными с сетью. Сеть просто недостаточно надежна, это не похоже на то, что вы вызываете функцию от одного устройства к другому. Любая достойная структура будет раскрывать всю эту функциональность просто потому, что любое приличное сетевое приложение должно сделать информацию доступной для конечного пользователя. Тем не менее, учитывая «взгляд» вашего ожидаемого API, загляните в SOAP. –

+0

@Cosmin: +1, а также для предложения SOAP. Это позволит универсальность отправки материалов на другую сторону, в то время как остается возможность «просто» WinINet или Indy HTTPGet отправить запрос и получить ответ. Другой конец будет немного более активным, но использование webbrokerbridge должно быть довольно легким для реализации. Извините, Mawg: не делайте что-нибудь, чтобы лететь, чтобы помочь вам. –

+0

Я предполагаю, что для Delphi не существует универсальной, единой платформы для всех. Реализация зависит от ваших точных спецификаций - например: нужно ли только приложениям обмениваться данными между этими двумя компьютерами, или может быть задействовано больше компьютеров сейчас или позже? Если да, то какая топология - один компьютер как центральный «сервер» или «мастер» (или «брокер сообщений»)? Или это одноранговая связь, где компьютеры могут напрямую разговаривать друг с другом? – mjn

ответ

3

Настоящий ответ на этот вопрос состоит в том, что вам нужно только научиться пользоваться Indy. Чтобы доказать свою точку зрения, я дам вам блок на 89 строк, который на самом деле реализует все, что вы просили, плюс образец доказательной концепции того, как его использовать.

Перед тем, как показать код, который я хотел бы отметить:

  • 89 строк кода нельзя назвать рамки. Это просто тонкая обертка, которая просто не стоит. Рано или поздно вы столкнетесь с материалами, требующими прямого доступа к основанной системе Indy.
  • Кто-то, у кого больше опыта в Indy, вероятно, написал бы это, используя еще меньше строк кода.
  • Я мог бы даже сделать его короче, так как я включил два перегруженных метода «StartServer» для удобства демонстрации.
  • Реализация этого с использованием компонентов, упавших на форму, приведет к сокращению количества строк.

Вот "структура" единица:

unit UTcpIntercom; 

interface 

uses IdContext, IdCustomTCPServer, IdTCPServer, IdBaseComponent, 
    IdComponent, IdTCPConnection, IdTCPClient, SysUtils; 

type 

    EIntercomError = class(Exception); 
    TReceivedText = procedure(const TextFromClient:string; var Response:string) of object; 
    TReceivedTextProc = procedure(const TextFromClient:string; var Response:string); 

    TIntercomServer = class(TIdCustomTCPServer) 
    protected 
    Event: TReceivedText; 
    Proc: TReceivedTextProc; 
    HostGreeting: string; 
    public 
    function DoExecute(AContext: TIdContext): Boolean; override; 
    end; 

function SendTextToComputer(const TextToSend, HostToSend, HostGreeting:string; PortNumber: Integer): string; 

function StartServer(PortNumber:Integer; const HostGreeting:string; OnReceivedText: TReceivedText):TIntercomServer;overload; 
function StartServer(PortNumber:Integer; const HostGreeting:string; OnReceivedText: TReceivedTextProc):TIntercomServer;overload; 

implementation 

function SendTextToComputer(const TextToSend, HostToSend, HostGreeting:string; PortNumber: Integer): string; 
var Id: TIdTCPClient; 
begin 
    Id := TIdTCPClient.Create(nil); 
    try 
    Id.Host := HostToSend; 
    Id.Port := PortNumber; 
    Id.Connect; 
    try 
     if Id.IOHandler.ReadLn <> HostGreeting then 
     raise EIntercomError.Create('Host is invalid: ' + HostToSend); 
     Id.IOHandler.WriteLn(TextToSend); 
     Result := Id.IOHandler.ReadLn; 
     Id.Disconnect; 
    finally Id.Disconnect; 
    end; 
    finally Id.Free; 
    end; 
end; 

function StartServer(PortNumber:Integer; const HostGreeting:string; OnReceivedText: TReceivedText):TIntercomServer;overload; 
begin 
    Result := TIntercomServer.Create(nil); 
    Result.Bindings.Add.Port := PortNumber; 
    Result.HostGreeting := HostGreeting; 
    Result.Event := OnReceivedText; 
    Result.Active := True; 
end; 

function StartServer(PortNumber:Integer; const HostGreeting:string; OnReceivedText: TReceivedTextProc):TIntercomServer;overload; 
begin 
    Result := TIntercomServer.Create(nil); 
    Result.Bindings.Add.Port := PortNumber; 
    Result.HostGreeting := HostGreeting; 
    Result.Proc := OnReceivedText; 
    Result.Active := True; 
end; 

{ TIntercomServer } 

function TIntercomServer.DoExecute(AContext: TIdContext): Boolean; 
var Text, Response: string; 
begin 
    AContext.Connection.IOHandler.WriteLn(HostGreeting); 
    Text := AContext.Connection.IOHandler.ReadLn; 
    Response := ''; 
    if Assigned(Event) then 
    Event(Text, Response) 
    else if Assigned(Proc) then 
    Proc(Text, Response) 
    else 
    Response := 'No handler assigned.'; 
    AContext.Connection.IOHandler.WriteLn(Response); 
    AContext.Connection.Disconnect; 

    Result := True; 
end; 

end. 

Вот код, который использует устройство. Обратите внимание на DoSomethingWithTextFromClient, это по существу ваш метод ProcessReceivedStringAndReply. Также обратите внимание на использование StartServer и SendTextToComputer.

program Project9; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils, 
    UTcpIntercom in 'UTcpIntercom.pas'; 

procedure DoSomethingWithTextFromClient(const TextFromClient: string; var Response:string); 
var i: Integer; 
    C: Char; 
    Len: Integer; 
begin 
    Response := TextFromClient; 
    Len := Length(Response); 
    for i:=1 to (Length(Response) div 2) do 
    begin 
    C := Response[Len-i+1]; 
    Response[Len-i+1] := Response[i]; 
    Response[i] := C; 
    end; 
end; 

begin 
    try 

    try 
     with StartServer(1000, 'Test', @DoSomethingWithTextFromClient) do 
     begin 
     WriteLn(SendTextToComputer('12345678', '127.0.0.1', 'Test', 1000)); 
     Free; 
     end; 

     Readln; 

    except on E:Exception do 
     begin 
     WriteLn(E.ClassName); 
     WriteLn(E.Message); 
     Readln; 
     end; 
    end; 

    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
end. 
+0

+1 Другими словами, компетенция не подлежит замене. –

+1

В основном я начал с нескольких строк кода вокруг клиентского/серверного соединения Indy TCP (как указано выше). Около 8 лет вниз по трассе, и около 100 линий выросли примерно до 10 000, чтобы обрабатывать общую коммуникацию сообщений, как синхронную, так и асинхронную, самовоспроизводящуюся связь и т. Д. Подобно потоковому, если вы действительно не хотите делать что-то с нуля и имеете много времени, чтобы сделать это, просто имеет смысл начать с чужой рамки. – Misha

+0

+1 спасибо dmy (и, вероятно, ответ, как только я поиграл с ним). Пожалуйста, прочтите нижнюю часть обновленного вопроса, чтобы узнать, во что я веду. – Mawg

4

У меня есть бесплатный фреймворк, который сделает все это. Преимущество состоит в том, что вы можете использовать его без каких-либо знаний сокетов. Вы можете безопасно игнорировать соединения и разъединения, потому что все это обрабатывается каркасом (базовая инфраструктура связи поддерживает непрерывное соединение через настраиваемые пинги и т. Д.). В инфраструктуру также встроена модель потоковой передачи сообщений. У меня есть демо для вашего точного примера. Недостатком является, очевидно, крутая кривая обучения. Посмотрите на http://www.csinnovations.com/framework_delphi.htm

+0

Как ваша инфраструктура обрабатывает длительные периоды простоя сети? –

+2

Очевидно, что вы не можете общаться между двумя узлами, которые не могут разговаривать друг с другом. Структура управляет каждым соединением клиент/сервер TCP. Если вам нужна избыточность, то это зависит от дизайна системной архитектуры. Конечно, путь - это создание сервисов более высокого уровня поверх распределенной системы, что я и сделал, но это не является частью свободной структуры. – Misha

+0

+1 Спасибо, Миша. Теперь я просматриваю ваш код и опубликую свое впечатление здесь. Похоже, вы поняли, чего я хочу. Будем надеяться, что это мой мифический «Layer 2» ;-) – Mawg

Смежные вопросы