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ć.
Tutaj jest wersja, która działa na Windows 10 i powiem szczerze jeszcze nie miałem żadnych problemów:
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?
Jak zrobiłem while to aplikacja się zawiesza i po chwili wyskakuje komunikat - "Program TCPServer nie odpowiada..."
Dziwne bo to niby w oddzielnym wątku :/
Próbowałeś debugować serwer i sprawdzać co odbiera? Po stronie Delphi wszytko się wysyła.
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.
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ą??
A tam nie brakuje odpowiedzi dla klienta coś w stylu stream.Write(...
? Może właśnie klient cały czas czeka na odpowiedź.
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.
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.
jak to ma działać jeśli nie utworzyłeś obiektu TcpClient1
? Sama deklaracja zmiennych to za mało.
AV
masz jak w banku
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?
TcpClient1 := TTcpClient.Create(nil);
try
/// tutaj kod
///
///
finally
TcpClient1.Free;
end;
Dziękuję ;)