I'm currently converting someone else's code. It is written in C# Windows FORM. and I want it to be in C# WPF.
this is the original code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
namespace FileReceiver
{
public partial class MainForm : Form
{
const int PORT = 1723;
public MainForm()
{
InitializeComponent();
}
private void resetControls()
{
progressBar1.Style = ProgressBarStyle.Marquee;
textBox1.Text = "Waiting for connection...";
}
protected override async void OnShown(EventArgs e)
{
// Listen
TcpListener listener = TcpListener.Create(PORT);
listener.Start();
textBox1.Text = "Waiting for connection...";
TcpClient client = await listener.AcceptTcpClientAsync();
NetworkStream ns = client.GetStream();
// Get file info
long fileLength;
string fileName;
{
byte[] fileNameBytes;
byte[] fileNameLengthBytes = new byte[4]; //int32
byte[] fileLengthBytes = new byte[8]; //int64
await ns.ReadAsync(fileLengthBytes, 0, 8); // int64
await ns.ReadAsync(fileNameLengthBytes, 0, 4); // int32
fileNameBytes = new byte[BitConverter.ToInt32(fileNameLengthBytes, 0)];
await ns.ReadAsync(fileNameBytes, 0, fileNameBytes.Length);
fileLength = BitConverter.ToInt64(fileLengthBytes, 0);
fileName = ASCIIEncoding.ASCII.GetString(fileNameBytes);
}
// Get permission
if (MessageBox.Show(String.Format("Requesting permission to receive file:\r\n\r\n{0}\r\n{1} bytes long", fileName, fileLength), "", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
// Set save location
SaveFileDialog sfd = new SaveFileDialog();
sfd.CreatePrompt = false;
sfd.OverwritePrompt = true;
sfd.FileName = fileName;
if (sfd.ShowDialog() != DialogResult.OK)
{
ns.WriteByte(0); // Permission denied
return;
}
ns.WriteByte(1); // Permission grantedd
FileStream fileStream = File.Open(sfd.FileName, FileMode.Create);
// Receive
textBox1.Text = "Receiving...";
progressBar1.Style = ProgressBarStyle.Continuous;
progressBar1.Value = 0;
int read;
int totalRead = 0;
byte[] buffer = new byte[32 * 1024]; // 32k chunks
while ((read = await ns.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await fileStream.WriteAsync(buffer, 0, read);
totalRead += read;
progressBar1.Value = (int)((100d * totalRead) / fileLength);
}
fileStream.Dispose();
client.Close();
MessageBox.Show("File successfully received");
resetControls();
}
}
}
I've successfully converted all the things in this code into WPF.
and the ONLY problem I am getting in WPF is this:
protected override async void OnShown(EventArgs e)
Error 8 'EmployeeLocatorv2.receiver.OnShown(System.EventArgs)': no suitable method found to override
This means that the class your main form is inheriting (probably Window or UserControl) does not have a virtual method named "OnShown" that you can override.
According to Chango V., Window.ContentRendered is the event you're looking for.
You can use the Window.ContentRendered event to know when the WPF form is rendered.
You can declare the event in your XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" ContentRendered="Window_ContentRendered_1">
And the corresponding code:
private void Window_ContentRendered_1(object sender, EventArgs e)
{
// Place your code here.
}
In WPF, ContentRendered has a similar behavior.
bool _hasShown;
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
if (!_hasShown)
{
_hasShown = true;
// void OnShown() code here!
}
}
Related
Receiving bytes here in this code(server)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
namespace ByteLengthReading
{
class Program
{
static void Main(string[] args)
{
StartServer();
}
private static TcpListener _listener;
public static void StartServer()
{
IPAddress localIPAddress = IPAddress.Parse("119.43.29.182");
IPEndPoint ipLocal = new IPEndPoint(localIPAddress, 8001);
_listener = new TcpListener(ipLocal);
_listener.Start();
WaitForClientConnect();
}
private static void WaitForClientConnect()
{
object obj = new object();
_listener.BeginAcceptTcpClient(new System.AsyncCallback(OnClientConnect), obj);
Console.In.ReadLine();
}
private static void OnClientConnect(IAsyncResult asyn)
{
try
{
TcpClient clientSocket = default(TcpClient);
clientSocket = _listener.EndAcceptTcpClient(asyn);
HandleClientRequest clientReq = new HandleClientRequest(clientSocket);
clientReq.StartClient();
}
catch (Exception ex)
{
throw ex;
}
WaitForClientConnect();
}
public class HandleClientRequest
{
TcpClient _clientSocket;
NetworkStream _networkStream = null;
public HandleClientRequest(TcpClient clientConnected)
{
this._clientSocket = clientConnected;
}
public void StartClient()
{
_networkStream = _clientSocket.GetStream();
WaitForRequest();
}
public void WaitForRequest()
{
byte[] buffer = new byte[_clientSocket.ReceiveBufferSize];
_networkStream.BeginRead(buffer, 0, buffer.Length, ReadCallback, buffer);
}
private void ReadCallback(IAsyncResult result)
{
NetworkStream networkStream = _clientSocket.GetStream();
byte[] buffer = new byte[16384];
int read = -1;
int totRead = 0;
using (FileStream fileStream = new FileStream(#"C:\Foo" + Guid.NewGuid().ToString("N") + ".txt", FileMode.Create))
{
while ((read = networkStream.Read(buffer, 0, buffer.Length)) > 0)
{
totRead += read;
fileStream.Write(buffer, 0, read);
Console.WriteLine("Total Read" + totRead);
//fileStream.Write(buffer, 0, totRead);
//fileStream.Close();
}
fileStream.Close();
}
}
}
}
Sending bytes (Client), Sending bytes of length 4047810. But the abover server code is recieving only 4039618 bytes. Please help someone. Don't know y? At the time of reading last set of data it is coming out of the while loop. Please test this code and tell me where the problem lies.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Drawing;
using System.Threading;
namespace ByteLengthSending
{
class Program
{
static void Main(string[] args)
{
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(IPAddress.Parse("119.43.29.182"), 8001);
//IPAddress ipAd = IPAddress.Parse("119.43.29.182");
//TcpClient client = new TcpClient(ipAd.ToString(), 8001);
//NetworkStream stream = client.GetStream();
int totread = 0;
byte[] longBuffer = new byte[3824726];
byte[] buffer = new byte[4096];
using (var fileStream = File.OpenRead("C:/Foo.txt"))
{
while (true)
{
int read = fileStream.Read(buffer, 0, buffer.Length);
totread += read;
if (read <= 0)
{
break;
}
for (int sendBytes = 0; sendBytes < read; sendBytes += client.Send(buffer, sendBytes, read - sendBytes, SocketFlags.None))
{
}
}
}
client.Close();
Console.WriteLine("Total Read" + totread);
Console.In.ReadLine();
}
}
}
Here is a sample which uses my library Griffin.Framework to transmit a file (Apache license).
All you need to do is to install the nuget package "griffin.framework" and then create a console application and replace Program class with the following:
class Program
{
static void Main(string[] args)
{
var server = new ChannelTcpListener();
server.MessageReceived = OnServerReceivedMessage;
server.Start(IPAddress.Any, 0);
var client = new ChannelTcpClient<object>(new MicroMessageEncoder(new DataContractMessageSerializer()),
new MicroMessageDecoder(new DataContractMessageSerializer()));
client.ConnectAsync(IPAddress.Loopback, server.LocalPort).Wait();
client.SendAsync(new FileStream("TextSample.txt", FileMode.Open)).Wait();
Console.ReadLine();
}
private static void OnServerReceivedMessage(ITcpChannel channel, object message)
{
var file = (Stream) message;
var reader = new StreamReader(file);
var fileContents = reader.ReadToEnd();
Console.WriteLine(fileContents);
}
}
The library can send/receive any type of stream of any size (as long as the size is known). The client will automatically create a MemoryStream or FileStream depending on the stream size.
I'm trying to make a video conferencing application (written in c#) that would allow 2 users to video conference using TCP. In addition, users can text chat separately. Right now, I have a working video stream, yet don't have the audio working yet. I'm unsure of how to access the microphone, stream it using TCP, and then play it on the other user's speakers as I'm relatively new to c# and brand new to using media.
If anyone could point me towards sample code, help me know how to access the mic, or anything else you think would help me, that'd be great.
I'm attaching my code as is for reference.
WEBCAM.cs
using System;
using System.IO;
using System.Linq;
using System.Text;
using WebCam_Capture;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
using System.Net;
using System.Net.Sockets;
using System.Windows;
namespace DuckTalk
{
class WebCam
{
const int TEXT_VIDEO_NUM = 45674;
private System.Windows.Controls.TextBox _hostIpAddressBox;
private WebCamCapture webcam;
private int FrameNumber = 30;
public void InitializeWebCam(ref System.Windows.Controls.TextBox hostIpAddressBox)
{
webcam = new WebCamCapture();
webcam.FrameNumber = ((ulong)(0ul));
webcam.TimeToCapture_milliseconds = FrameNumber;
webcam.ImageCaptured += new WebCamCapture.WebCamEventHandler(webcam_ImageCaptured);
_hostIpAddressBox = hostIpAddressBox;
}
void webcam_ImageCaptured(object source, WebcamEventArgs e)
{
TcpClient connection = null;
NetworkStream stream = null;
byte[] imgBytes;
try
{
//Set up IPAddress
IPAddress ipAddress = IPAddress.Parse(_hostIpAddressBox.Text);
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, TEXT_VIDEO_NUM);
//Connect to TCP
connection = new TcpClient();
connection.Connect(ipLocalEndPoint);
// Get a client stream for reading and writing.
stream = connection.GetStream();
//Send image as bytes
imgBytes = ImageByteConverter.ImageToBytes((System.Drawing.Bitmap)e.WebCamImage);
stream.Write(imgBytes, 0, imgBytes.Length);
}
catch (Exception error)
{
MessageBox.Show("ERROR: " + error.Message);
}
finally
{
// Close everything.
if (connection != null)
connection.Close();
if (stream != null)
stream.Close();
}
}
public void Start()
{
webcam.TimeToCapture_milliseconds = FrameNumber;
webcam.Start(0);
}
public void Stop()
{
webcam.Stop();
}
}
}
ImageByteConverter.cs
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections.Generic;
using System.Windows.Media.Imaging;
namespace DuckTalk
{
class ImageByteConverter
{
public static byte[] ImageToBytes(System.Drawing.Bitmap bitmap)
{
byte[] byteArray;
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
public static BitmapImage BytesToImage(byte[] imgBytes)
{
var image = new BitmapImage();
image.BeginInit();
image.StreamSource = new System.IO.MemoryStream(imgBytes);
image.EndInit();
return image;
}
}
}
Window1.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Net;
using System.Net.Sockets;
namespace DuckTalk
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class MainWindow : Window
{
const int TEXT_PORT_NUM = 45673;
const int TEXT_VIDEO_NUM = 45674;
WebCam webcam;
public MainWindow()
{
InitializeComponent();
}
private void mainWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
webcam = new WebCam();
webcam.InitializeWebCam(ref xaml_hostTextBox);
var _backgroundIMWorker = new BackgroundWorker();
var _backgroundVidWorker = new BackgroundWorker();
_backgroundIMWorker.WorkerReportsProgress = true;
_backgroundVidWorker.WorkerReportsProgress = true;
// Set up the Background Worker Events
_backgroundIMWorker.DoWork += new DoWorkEventHandler(keepListeningForInstantMessages);
_backgroundVidWorker.DoWork += new DoWorkEventHandler(keepListeningForVideoMessages);
// Run the Background Workers
_backgroundIMWorker.RunWorkerAsync();
_backgroundVidWorker.RunWorkerAsync();
}
///////////////////////////////////////////////////////////////////////////////////////////////
//
//
// The next 2 functions take care of the instant messaging part of the program
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////////
private void keepListeningForInstantMessages(object sender, DoWorkEventArgs e)
{
Action<string> displayIncomingMessage = (incomingMsg) =>
{
xaml_incomingTextBox.Text += "\n\nINCOMING MESSAGE: " + incomingMsg;
xaml_incomingTextScroll.ScrollToBottom();
};
Socket connection;
Byte[] data;
String msg;
// create the socket
Socket listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// bind the listening socket to the port
IPEndPoint ep = new IPEndPoint(IPAddress.Any, TEXT_PORT_NUM);
listenSocket.Bind(ep);
while (true)
{
msg = "";
data = new Byte[3000];
// start listening
listenSocket.Listen(1);
//Received a connection
connection = listenSocket.Accept();
//Get Data
connection.Receive(data);
//Get the message in string format
msg = System.Text.Encoding.Default.GetString(data);
msg = msg.Substring(0,msg.IndexOf((char)0));
//Send message to the UI
xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingMessage, msg);
connection.Close();
}
}//end of keepListeningForInstantMessages
void SendInstantMsg(object sender, RoutedEventArgs e)
{
TcpClient connection = null;
NetworkStream stream = null;
byte[] data;
xaml_incomingTextBox.Text += "\n\nOUTGOING MESSAGE: " + xaml_outgoingTextBox.Text;
try
{
//Set up IPAddress
IPAddress ipAddress = IPAddress.Parse(xaml_hostTextBox.Text);
IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, TEXT_PORT_NUM);
//Connect to TCP
connection = new TcpClient();
connection.Connect(ipLocalEndPoint);
//Convert text to bytes
data = System.Text.Encoding.ASCII.GetBytes(xaml_outgoingTextBox.Text);
// Get a client stream for reading and writing.
stream = connection.GetStream();
// Send the message to the connected TcpServer.
stream.Write(data, 0, data.Count());
xaml_outgoingTextBox.Text = "";
}
catch (Exception error)
{
MessageBox.Show("ERROR: " + error.Message);
}
finally
{
// Close everything.
if (connection != null)
connection.Close();
if (stream != null)
stream.Close();
}
}//end of SendInstantMsg
///////////////////////////////////////////////////////////////////////////////////////////////
//
//
// The next 2 functions take care of the video part of the program
//
//
//
///////////////////////////////////////////////////////////////////////////////////////////////
private void keepListeningForVideoMessages(object sender, DoWorkEventArgs e)
{
Action<Byte[]> displayIncomingVideo = (incomingImgBytes) =>
{
xaml_incomingVideo.Source = ImageByteConverter.BytesToImage(incomingImgBytes);
};
Socket connection;
Byte[] incomingBytes;
Byte[] data;
int offset;
int numOfBytesRecieved;
// create the socket
Socket listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// bind the listening socket to the port
IPEndPoint ep = new IPEndPoint(IPAddress.Any, TEXT_VIDEO_NUM);
listenSocket.Bind(ep);
while (true)
{
offset = 0;
numOfBytesRecieved = -1;
incomingBytes = new Byte[300000];
// start listening
listenSocket.Listen(1);
//Received a connection
connection = listenSocket.Accept();
//Get all the data from the connection stream
while (numOfBytesRecieved != 0)
{
numOfBytesRecieved = connection.Receive(incomingBytes, offset, 10000, SocketFlags.None);
offset += numOfBytesRecieved;
}
data = new Byte[offset];
Array.Copy(incomingBytes, data, offset);
//Send image to the UI
xaml_incomingTextBox.Dispatcher.BeginInvoke(displayIncomingVideo, data);
connection.Close();
}
}//end of keepListeningForVideoMessages
private void SendVideoMsg(object sender, RoutedEventArgs e)
{
xaml_incomingVideo.Visibility = Visibility.Visible;
xaml_StopVideoButton.Visibility = Visibility.Visible;
xaml_SendTextButton.Visibility = Visibility.Hidden;
webcam.Start();
}
private void StopVideoMsg(object sender, RoutedEventArgs e)
{
xaml_incomingVideo.Visibility = Visibility.Hidden;
xaml_StopVideoButton.Visibility = Visibility.Hidden;
xaml_SendTextButton.Visibility = Visibility.Visible;
webcam.Stop();
}
}//end of Class
}//end of NameSpace
You should try downloading NAudio, it is an open source audio library. It comes with a demo on how to stream audio using UDP from one pc to another; it is in the NAudioDemo app called "Network Chat".
http://naudio.codeplex.com/
TCP which you are currently using is not really recommended for audio. Use UDP instead
http://www.onsip.com/about-voip/sip/udp-versus-tcp-for-voip
Alternatively, if you do not want to reinvent the wheel ( I am not sure what is your ultimate goal with your project ), you can try downloading our iConf.NET video conferencing SDK that does most of the leg work for you ( but is not free )
http://avspeed.com/
I am trying to build a basic server client application in winforms. However the server does nothing. Just sort of opens up and hangs if i may say so. What am i doing wrong. I made the application as follows:
The Server Winform
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;
using System.IO;
namespace ServerWinForms
{
public partial class Form1 : Form
{
public delegate void AddText(TcpClient tcp, RichTextBox rtb);
public AddText myDelegate;
Thread myThread;
public Form1()
{
InitializeComponent();
myDelegate = new AddText(ClientSession);
}
void begin(Object obj)
{
var loaclAddress = IPAddress.Parse("127.0.0.1");
var tcpListener = new TcpListener(loaclAddress, 81);
tcpListener.Start();
while (true)
{
var tcpClient = tcpListener.AcceptTcpClient();
Form1 myForm1 = (Form1)obj;
myForm1.Invoke(myForm1.myDelegate);
//rtb.AppendText("Waiting for connection ");
// Console.WriteLine("Waiting for a connection");
//rtb.AppendText("Client Accepted ");
//Console.WriteLine("Client Accepted");
/*Thread thread = new Thread(() => ClientSession(tcpClient))
{
IsBackground = true
};
thread.Start();
//Console.WriteLine("Client Session thread started");
*/
}
}
private static bool tryRead(Stream stream, byte[] buffer, int offset, int count)
{
int bytesRead;
while (count > 0 && (bytesRead = stream.Read(buffer, offset, count)) > 0)
{
offset += bytesRead;
count -= bytesRead;
}
return count == 0;
}
public static void ClientSession(TcpClient tcpClient, RichTextBox rtb)
{
const int totalByteBuffer = 4096;
byte[] buffer = new byte[256];
// UC ucObj = new UC();
using (var networkStream = tcpClient.GetStream())
using (var bufferedStream = new BufferedStream(networkStream, totalByteBuffer))
while (true)
{
if (!tryRead(bufferedStream, buffer, 0, 1))
{
break;
}
byte messageLen = buffer[0];
if (!tryRead(bufferedStream, buffer, 1, messageLen))
{
break;
}
var message = Encoding.ASCII.GetString(buffer, 1, messageLen);
//Console.WriteLine(/*"Message Recieved: {0}", */ message);
RichTextBox rcb = new RichTextBox();
rtb.AppendText(message);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
myThread = new Thread(begin);
myThread.Start(this);
//begin();
}
}
}
The Client Winform (though i believe everything is in order here but still... )
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.IO;
namespace ClientWinForms
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private static byte[] msg2ByteArray(string message, Encoding enc)
{
var byteCount = enc.GetByteCount(message);
if (byteCount > byte.MaxValue)
{
throw new ArgumentException("Message size is greater than 255 bytes in the provided encoding");
}
var byteArray = new byte[byteCount + 1];
byteArray[0] = (byte)byteCount;
enc.GetBytes(message, 0, message.Length, byteArray, 1);
return byteArray;
}
void sendMsg()
{
String message;
using (var tcpClient = new TcpClient())
{
tcpClient.Connect("127.0.0.1", 81);
using (var networkStream = tcpClient.GetStream())
using (var bufferedStream = new BufferedStream(networkStream))
{
//while (true)
//{
byte[] buffer = new byte[256];
//Console.WriteLine("Write Message");
message = richTextBox.Text;
var byteArray = msg2ByteArray(message, Encoding.ASCII);
bufferedStream.Write(byteArray, 0, byteArray.Length);
bufferedStream.Flush();
//}
}
}
}
private void btnSend_Click(object sender, EventArgs e)
{
sendMsg();
}
}
}
kewal, your code looks good and your program also. i also liked that you share all the code, it is most frustrating when i need to ask almost every other asked to do that.
now to the problem. you use tcpListener.Start(); in your server.
as we can read here:
"If a connection request is received, the Start method will queue
the request and continue listening for additional requests until you
call the Stop method"
i believe what you wanted is to use AcceptSocket() method - read
here
i can suggest: use different port. low number ports are taken
already and might not work. i think 81 if for http's, though i'm not
sure
EDIT
3. for the client use this MSDN example to see if the basic
example works for you
i made a client and server socket based gui app in which screen is captured and via socket it is transfered to desired listner but i am getting a black out put image a receiver end or client the image is there at server but cannot show it in my client app it just show a black pic?
code as : server
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.Drawing.Imaging;
using System.Net.Sockets;
using System.IO;
using System.Net;
namespace LanMonitoring
{
public partial class Form1 : Form
{
private static Bitmap bmpScreenshot;
bool start = false;
private static Graphics gfxScreenshot;
public Form1()
{
InitializeComponent();
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
button2.Enabled = true;
start = true;
fillpic();
}
public void fillpic()
{
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
pictureBox1.Image = bmpScreenshot;
sendbmp(bmpScreenshot);
}
private void button2_Click(object sender, EventArgs e)
{
button1.Enabled = true;
button2.Enabled = false;
start = false;
}
public void sendbmp(Bitmap bmp)
{
Socket mm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(textBox1.Text), 5002);
try
{
mm.Connect(remoteEP);
}
catch (Exception)
{
sendbmp(bmpScreenshot);
}
Image temp = bmp;
byte[] buf = imageToByteArray(temp);
mm.Send(buf);
mm.Close();
}
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
}
client as:
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.Sockets;
using System.IO;
using System.Net;
namespace LanReciver
{
public partial class Client : Form
{
byte[] buf = new byte[5000];
public Client()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
public void call()
{
Socket mm = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mm.Bind(new IPEndPoint(0, 5002));
mm.Listen(100);
Socket acc = mm.Accept();
buf = new byte[acc.SendBufferSize];
int byteread = acc.Receive(buf);
byte[] rev = new byte[byteread];
for (int i = 0; i < byteread; i++)
{
rev[i] = buf[i];
}
byteArrayToImage(rev);
mm.Close();
acc.Close();
call();
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
call();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("Recieved");
}
}
}
Here's a reasonably complete (albeit quick and dirty) solution:
Server:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace ImageServer
{
static class Program
{
static void Main()
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Bind(new IPEndPoint(IPAddress.Any, 23456));
socket.Listen(100);
while (true)
{
using (var client = socket.Accept())
{
var bounds = Screen.PrimaryScreen.Bounds;
var bitmap = new Bitmap(bounds.Width, bounds.Height);
try
{
while (true)
{
using (var graphics = Graphics.FromImage(bitmap))
{
graphics.CopyFromScreen(bounds.X, 0, bounds.Y, 0, bounds.Size);
}
byte[] imageData;
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
imageData = stream.ToArray();
}
var lengthData = BitConverter.GetBytes(imageData.Length);
if (client.Send(lengthData) < lengthData.Length) break;
if (client.Send(imageData) < imageData.Length) break;
Thread.Sleep(1000);
}
}
catch
{
break;
}
}
}
}
}
}
}
Client (a form with a single button: "button1" and a single pictureBox: "pictureBox1"):
using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace ImageClient
{
public partial class Form1 : Form
{
private Bitmap _buffer;
public Form1()
{
InitializeComponent();
}
private void Button1Click(object sender, EventArgs e)
{
button1.Enabled = false;
ThreadPool.QueueUserWorkItem(GetSnapshots);
}
private void GetSnapshots(object state)
{
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
socket.Connect(new IPEndPoint(IPAddress.Loopback, 23456));
while (true)
{
var lengthData = new byte[4];
var lengthBytesRead = 0;
while (lengthBytesRead < lengthData.Length)
{
var read = socket.Receive(lengthData, lengthBytesRead, lengthData.Length - lengthBytesRead, SocketFlags.None);
if (read == 0) return;
lengthBytesRead += read;
}
var length = BitConverter.ToInt32(lengthData, 0);
var imageData = new byte[length];
var imageBytesRead = 0;
while (imageBytesRead < imageData.Length)
{
var read = socket.Receive(imageData, imageBytesRead, imageData.Length - imageBytesRead, SocketFlags.None);
if (read == 0) return;
imageBytesRead += read;
}
using (var stream = new MemoryStream(imageData))
{
var bitmap = new Bitmap(stream);
Invoke(new ImageCompleteDelegate(ImageComplete), new object[] { bitmap });
}
}
}
}
private delegate void ImageCompleteDelegate(Bitmap bitmap);
private void ImageComplete(Bitmap bitmap)
{
if (_buffer != null)
{
_buffer.Dispose();
}
_buffer = new Bitmap(bitmap);
pictureBox1.Size = _buffer.Size;
pictureBox1.Invalidate();
}
private void PictureBox1Paint(object sender, PaintEventArgs e)
{
if (_buffer == null) return;
e.Graphics.DrawImage(_buffer, 0, 0);
}
}
}
Just because you are sending the image with a single call to Send(...), it's very unlikely (unless the image is small, which if it's a screenshot, it probably isn't) that it will be received completely with a single call to Receive(...) on the client side.
You will need to call Receive(...) repeatedly, building up the received image buffer until Receive(...) returns 0, indicating that the socket has been closed. You should then have the complete image for display.
Not sure what your actual problem is but I notice there is a potential bug in byteArrayToImage(); you must keep the stream open for the lifetime of the image (yeah, it's not the most usable .NET API method!): http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
I used tcp client and listner method and it worked fine but with one prob on the reciver side it only shows the 1/4 of the image and throws an exception connection was not established .. now what is the prb
public partial class Form1 : Form
{
private static Bitmap bmpScreenshot;
bool start = false;
private static Graphics gfxScreenshot;
public Form1()
{
InitializeComponent();
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
button2.Enabled = true;
start = true;
fillpic();
backgroundWorker1.RunWorkerAsync();
}
public void fillpic()
{
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
pictureBox1.Image = bmpScreenshot;
}
private void button2_Click(object sender, EventArgs e)
{
button1.Enabled = true;
button2.Enabled = false;
start = false;
}
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
}
public void caal()
{
TcpClient TCPC = new TcpClient();
TCPC.Connect("127.0.0.1", 5002);
if (TCPC.Connected)
{
NetworkStream ns = TCPC.GetStream();
while (ns.CanWrite)
{
fillpic();
byte[] data = imageToByteArray(bmpScreenshot);
ns.Write(data, 0, data.Length);
}
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
caal();
}
}
Like #Iridium mentioned, you need to loop Read()-ing until no more data is received.
Also, please look at MemoryStream to replace all the array element shuffling.
A simple Array.CopyTo would already be a vast improvent over the code you have to copy byte arrays
I have a Silverlight 3 app that allows the user to upload images, and then is supposed to display them. The image gets uploaded fine (I can view it in the browser), but I get the following error from Silverlight:
Message: Sys.InvalidOperationException: ImageError error #4001 in control 'Xaml1': AG_E_NETWORK_ERROR
Line: 453
Char: 17
Code: 0
URI: http://www.greektools.net/ScriptResource.axd?d=J4B4crBmh4Qxr3eVyHw3QRgAKpCaa6XLu8H_2zpAs7eWeADXG9jQu_NCTxorhOs1x6sWoSKHEqAL37LcpWepfg2&t=fffffffffd030d68
Fiddler reports: There is a problem with the resource you are looking for, and it cannot be displayed.
Thanks in advance for your help.
Here it is in three files. This is also available at my blog, which is listed in my profile.
XAML (imageuploader.xaml):
<UserControl x:Class="ImageEditor.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480" MouseMove="UserControl_MouseMove">
<Grid x:Name="LayoutRoot" Background="Azure" Width="800" Height="600">
<Image x:Name="MainImage" Source="images/image.jpg" Width="300" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
<Button x:Name="UploadImage" Click="UploadImage_Click" Content="Upload"></Button>
</Grid>
</UserControl>
Code (imageuploader.xaml.cs):
private void UploadImage_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.Multiselect = false;
dlg.Filter = "All files (*.*)|*.*|PNG Images (*.png)|*.png";
bool? retval = dlg.ShowDialog();
if (retval != null && retval == true)
{
UploadFile(dlg.File.Name, dlg.File.OpenRead());
StatusText.Text = dlg.File.Name;
}
else
{
StatusText.Text = "No file selected...";
}
}
private void UploadFile(string fileName, Stream data)
{
string host = Application.Current.Host.Source.AbsoluteUri;
host = host.Remove(host.IndexOf("/ClientBin"));
UriBuilder ub = new UriBuilder(host + "/receiver.ashx");
ub.Query = string.Format("filename={0}", fileName);
WebClient c = new WebClient();
c.OpenWriteCompleted += (sender, e) =>
{
PushData(data, e.Result);
e.Result.Close();
data.Close();
};
c.WriteStreamClosed += (sender, e) =>
{
LoadImage(fileName);
};
c.OpenWriteAsync(ub.Uri);
}
private void LoadImage(string fileName)
{
//
// Creating WebClient object and setting up events
//
WebClient downloader = new WebClient();
downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
//downloader.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloader_DownloadProgressChanged);
//
// Specify Image to load
//
string host = Application.Current.Host.Source.AbsoluteUri;
host = host.Remove(host.IndexOf("/ClientBin"));
fileName = host + "/images/" + fileName;
downloader.OpenReadAsync(new Uri(fileName, UriKind.Absolute));
}
void downloader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
//
// Create a new BitmapImage and load the stream
//
BitmapImage loadedImage = new BitmapImage();
loadedImage.SetSource(e.Result);
//
// Setting our BitmapImage as the source of a imageControl control I have in XAML
//
MainImage.Source = loadedImage;
}
private void PushData(Stream input, Stream output)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) != 0)
{
output.Write(buffer, 0, bytesRead);
}
}
Handler (receiver.ashx):
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class receiver : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string filename = context.Request.QueryString["filename"].ToString();
using (FileStream fs = File.Create(context.Server.MapPath("~/images/" + filename)))
{
SaveFile(context.Request.InputStream, fs);
}
}
private void SaveFile(Stream stream, FileStream fs)
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
fs.Write(buffer, 0, bytesRead);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}