Witam, mam problem z odbiorem danych po stronie klienta. Wykorzystuję asynchroniczny serwer w którym chcę wysyłać obraz.
Oto kod źródłowy serwera:
public class StateObject
{
// Gniazdo klienta.
public Socket workSocket = null;
// Rozmiar bufora odbioru.
public const int BufferSize = 1024;
// Bufor odbioru.
public byte[] buffer = new byte[BufferSize];
// Odebrany ciąg danych.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener : Form1
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
// Utworzenie lokalnego punktu końcowego dla gniazda.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, socketIn);
// Stworzenie gniazda TCP/IP.
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
// Ustaw zdarzenie do stanu niesygnalizowanego.
allDone.Reset();
// Włącz asynchroniczne gniazdo do nasłuchiwania połączeń.
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Stwórz obiekt stanu.
StateObject state = new StateObject();
state.workSocket = handler;
obraz = makeScreenShot();
// Konwertuj obraz na dane typu byte
MemoryStream ms = new MemoryStream();
obraz.Save(ms, ImageFormat.Jpeg);
byte[] byteObraz = ms.GetBuffer();
ms.Close();
// Rozpocznij wysyłanie danych do urządzenia zdalnego.
handler.BeginSend(byteObraz, 0, byteObraz.Length, 0, new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
// Zakończ wysyłanie danych do urządzenia zdalnego.
int bytesSent = handler.EndSend(ar);
string test = bytesSent.ToString();
MessageBox.Show("Sent " + test + " bytes to client.",test);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
Niestety po stronie klienta otrzymuję wyjątek dla metody ReadBytes klasy BinaryReader że parametr count musi być nieujemny. Po sprawdzeniu debuggerem wartość ta rzeczywiście jest ujemna. Wnioskuję że dane w ogóle nie dotarły pomimo że po stronie serwera otrzymałem komunikat że:
"Sent " + test + " bytes to client."
Poniżej znajduje się kod klienta:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string host = textBox1.Text;
int port = System.Convert.ToInt16(numericUpDown1.Value);
try
{
TcpClient klient = new TcpClient(host, port);
NetworkStream ns = klient.GetStream();
while (klient.Connected)
{
byte[] obrazByte;
using (BinaryReader odczytObrazu = new BinaryReader(ns))
{
int rozmiarObrazu = odczytObrazu.ReadInt32();
obrazByte = odczytObrazu.ReadBytes(rozmiarObrazu);
}
using (MemoryStream ms = new MemoryStream(obrazByte))
{
Image obraz = Image.FromStream(ms);
pictureBox1.Image = obraz;
}
}
klient.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
Moim zamiarem jest ciągłe wysyłanie obrazu jeden za drugim aby otrzymać przyzwoity framerate (tak wiem że z tym jest temat rzeka, ale na razie nie zagłębiam się skoro nie poradzę wysłać jednego obrazu).