Komunikacja TCP pomiędzy Delphi (klient) a C# (serwer)

0

Z tego co pamiętam to Turbo Delphi ma problem z instalacją na Win10, nie ten .Net a starszego nie można dograć, przynajmniej rok temu mi się to nie udało. Jak będę miał chwilę to zobaczę na nowszym Delphi czy da się połączyć bez problemu i poprawnie komunikować.

0

Tutaj jest wersja, która działa na Windows 10 i powiem szczerze jeszcze nie miałem żadnych problemów:

http://www.andyaska.com/?act=download&id=34&mode=detail

0

A gdyby

                if (client.Connected) // If you are connected
                {
                    ServerReceive(); //Start Receiving
                }

zmienić na pętlę while a w procedurze ServerReceive sprawdzać czy są jakieś bajty do odczytania?

0

Jak zrobiłem while to aplikacja się zawiesza i po chwili wyskakuje komunikat - "Program TCPServer nie odpowiada..."

0

Dziwne bo to niby w oddzielnym wątku :/

0

Próbowałeś debugować serwer i sprawdzać co odbiera? Po stronie Delphi wszytko się wysyła.

0

Wygląda to tak jakby komunikat lecący do serwera C# nie zamykał przesyłu i serwer wyświetla komunikat, ale nie ma zamkniętego komunikatu, odbiera kolejne i kolejne, naciskam w kliencie disconnect, w serwerze Listen czyli uruchamiam od nowa i wtedy nagle wyświetla stare komunikaty od klienta.

0

https://msdn.microsoft.com/pl-pl/library/system.net.sockets.tcpclient.getstream(v=vs.110).aspx

Należy zamknąć NetworkStream po osiągnięciu przez wysyłanie i odbieranie danych. Zamykanie TcpClient nie NetworkStream.

Nie o to chodzi?

BTW Te teksty na MSDN to z translatora lecą??

0

A tam nie brakuje odpowiedzi dla klienta coś w stylu stream.Write(... ? Może właśnie klient cały czas czeka na odpowiedź.

0

To działa, ale nie zrobiłem jeszcze przesyłania obrazków:

Serwer:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace TCPServer
{
    public partial class Form1 : Form
    {
        private Socket newsock;
        private Socket client;
        private int recv;
        private IPEndPoint ipep;
        private IPEndPoint clientep;
        private byte[] data;

        public Form1()
        {
            InitializeComponent();
        }

        public void StartServer()
        {
            new Thread(() => // Thread (like Timer)
            {
                data = new byte[1024];
                ipep = new IPEndPoint(IPAddress.Any,
                                        9050);

                newsock = new
                    Socket(AddressFamily.InterNetwork,
                                SocketType.Stream, ProtocolType.Tcp);

                newsock.Bind(ipep);
                newsock.Listen(10);
                txtBox_Log.Text += "Czekam za klientem.... \r\n";
                client = newsock.Accept();
                clientep = (IPEndPoint)client.RemoteEndPoint;
                txtBox_Log.Text += "Connected with " + clientep.Address + " at port " + clientep.Port + "\r\n";

                try
                {
                    while (true)
                    {
                        data = new byte[1024];
                        recv = client.Receive(data);
                        if (recv == 0)
                            break;

                        txtBox_Log.Text += "!" + Encoding.ASCII.GetString(data, 0, recv) + "!";
                        // client.Send(data, recv, SocketFlags.None);
                    }
                }
                catch { }
            }).Start();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
           /* if (client.Connected) // if the client is connected
            {
                ServerSend(txtSend.Text); // uses the Function ClientSend and the msg as txtSend.Text
            }*/
        }

        private void btn_Close_Click(object sender, EventArgs e)
        {
            txtBox_Log.Text += "Przerwano połączenie z serwerem!! \r\n";
            client.Close();
            newsock.Close();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                client.Close();
                newsock.Close();
            }
            catch { }
        }

        private void btnStartConnection_Click(object sender, EventArgs e)
        {
            StartServer();
        }
    }
}

Klient:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Sockets;

type
  TForm1 = class(TForm)
    TcpClient1: TTcpClient;
    Edit1: TEdit;
    Button1: TButton;
    btn_Connect: TButton;
    btn_Send: TButton;
    btn_Disconnect: TButton;
    procedure Button1Click(Sender: TObject);
    procedure btn_DisconnectClick(Sender: TObject);
    procedure btn_SendClick(Sender: TObject);
    procedure btn_ConnectClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn_ConnectClick(Sender: TObject);
begin
  TcpClient1.Connect;
end;

procedure TForm1.btn_DisconnectClick(Sender: TObject);
begin
  TcpClient1.Disconnect;
end;

procedure TForm1.btn_SendClick(Sender: TObject);
begin
  TcpClient1.Sendln(edit1.text);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if TcpClient1.Connect then
  begin
    TcpClient1.Sendln(edit1.text);
    TcpClient1.Disconnect;
  end;
end;

end.
0

A kto z Was wie jak tego klienta okienkowego przerobić na konsolowy (klienta będzie wywoływany poprzez dll)? Zrobiłem coś takiego, ale nie działa:

program Project1;

{$APPTYPE CONSOLE}

uses
    SysUtils
  , StdCtrls
  , Sockets;

var
  TcpClient1: TTcpClient;
  a: Integer;

begin
  { TODO -oUser -cConsole Main : Insert code here }
  TcpClient1.Active := true;
  TcpClient1.RemoteHost := '127.0.0.1';
  TcpClient1.RemotePort := '9050';
  TcpClient1.Connect;

  TcpClient1.Sendln('Przesyłam tekst');
  TcpClient1.Disconnect;

   WriteLn('press any key to continue');
   Readln(a);
end.
1

jak to ma działać jeśli nie utworzyłeś obiektu TcpClient1 ? Sama deklaracja zmiennych to za mało.
AV masz jak w banku

0

Ok, rozumiem, ale niestety nie mam pojęcia jak to napisać. Deklaracja obiektów jest poprzez type, ale deklaruję to względem jakiej klasy? Mógłbyś to napisać, aby to zadziałało?

2
  TcpClient1 := TTcpClient.Create(nil);
  try
    /// tutaj kod
    ///
    ///

  finally
    TcpClient1.Free;
  end;
0

Dziękuję ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1