473,387 Members | 1,516 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Asynchronous image transfer over TCP/IP socket

Hi every1,

I am writing a small client/server application and in it I want to
send an image asynchronous from the client to the server through a TCP
socket. I found an example code on the MSDN site, which is actually
for sending strings. I tried to adapt this code so that the client
sends an image instead of a string. However, there is something wrong
on the server side (i guess)...
The server starts listening, the client starts sending and I become an
indication, that the server receives something... but doesn't stop
receiving. The else-condition in the function Send_Image() is never
reached.

As far as I understood the Microsoft-code, the data is being sent in
parts (every part is with the size of the buffer). That's why the
Read_Image() function is called as long as all the data is transfered
(that is exactly the if-condition - if bytesRead>0 ). I save these
data parts (in bytes) in an ArrayList and at the end I convert this
ArrayList to a byte array and then to a Bitmap.

Here is the code. Can anyone help me to find my mistake ... please, I
am stuck!!! :(
The client side:

public static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the remote device is "host.domain.com".
IPHostEntry ipHostInfo =
Dns.Resolve("host.domain.com");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);

// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();

// Send the image to the remote device.
string fName = @"\Program Files\Client\image.jpg"; //
path to image
SendImage(client, new Bitmap(fName));
sendDone.WaitOne();

// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();

// Write the response to the console.
Console.WriteLine("Response received : {0}",
response);
//System.Windows.Forms.MessageBox.Show("Otgovor
poluchen");

// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();

}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
//--------------------------------------------------------------------
//convet Image to byte[]
public static byte[] imageToByteArray(Bitmap imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.GetBuffer();
}
//--------------------------------------------------------------------
private static void SendImage(Socket client, Bitmap img)
{
// Convert the image to byte data
byte[] byteData = imageToByteArray(img);

// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
//--------------------------------------------------------------------
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;

// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.",
bytesSent); //this msg never shows up!

// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
The server side:

// State object for reading client data asynchronously
public class StateObject {
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024*10;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received image bytes
public ArrayList imageBytes = new ArrayList();
}
//----------------------------------------------------------------------
public static void StartListening() {
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];

// Establish the local endpoint for the socket.
// The DNS name of the computer running the listener is
"server.domain.com".
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

// Bind the socket to the local endpoint and listen for
incoming connections.
try {
listener.Bind(localEndPoint);
listener.Listen(100);

while (true) {
// Set the event to nonsignaled state.
allDone.Reset();

// Start an asynchronous socket to listen for
connections.
System.Windows.Forms.MessageBox.Show("Waiting for a
connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );

// Wait until a connection is made before continuing.
allDone.WaitOne();
}

} catch (Exception e) {
Console.WriteLine(e.ToString());
System.Windows.Forms.MessageBox.Show(e.ToString()) ;
}

System.Windows.Forms.MessageBox.Show("\nPress ENTER to
continue...");
Console.Read();

}
//----------------------------------------------------------------------
public static void AcceptCallback(IAsyncResult ar) {
// Signal the main thread to continue.
allDone.Set();

// Get the socket that handles the client request.
Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize,
0,
new AsyncCallback(Read_Image), state);
}
//--------------------------------------------------------
public static void Read_Image(IAsyncResult ar)
{
StateObject so = (StateObject)ar.AsyncState;
Socket s = so.workSocket;

int read = s.EndReceive(ar);

if (read 0)
{
//so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0,
read));
foreach (byte el in so.buffer)
{
so.imageBytes.Add(el);
}
s.BeginReceive(so.buffer, 0, StateObject.BufferSize, 0,new
AsyncCallback(Read_Image), so);
System.Windows.Forms.MessageBox.Show("read 0, call
Read_Image recursively");
}
else
{
System.Windows.Forms.MessageBox.Show("Else case");
if (so.imageBytes.Count 0)
{
//All of the data has been read, so displays it to the
console
byte[] imageBytesArray = new
byte[so.imageBytes.Count];
so.imageBytes.CopyTo(imageBytesArray);
myForm.pictureBox1.Image =
ImgConverter.byteArrayToImage(imageBytesArray);
//Send(s, "<EOF>");
//System.Windows.Forms.MessageBox.Show("Sent!");
}
System.Windows.Forms.MessageBox.Show("Receive done!");
Send(s, "<EOF>"); //this sends a msg to the client and
closes the socket connection. I didn't paste the function
s.Close();
}
}


Thanks in advance!

Cheers,
Vasil
Sep 8 '08 #1
1 7100
On Mon, 08 Sep 2008 15:11:04 -0700, keksy <va***********@gmail.comwrote:
[...]
As far as I understood the Microsoft-code, the data is being sent in
parts (every part is with the size of the buffer). That's why the
Read_Image() function is called as long as all the data is transfered
(that is exactly the if-condition - if bytesRead>0 ). I save these
data parts (in bytes) in an ArrayList and at the end I convert this
ArrayList to a byte array and then to a Bitmap.

Here is the code. Can anyone help me to find my mistake ... please, I
am stuck!!! :(
It's hard to say, as you didn't post a concise-but-complete code sample.
But a few things jump out at me during a cursory scan of the code (it's
too sloppy for me to try to decipher every individual statement):

-- You're using the async API to do this. As much as I am a big fan
of the async API for network i/o, you should first get it working
synchronously. And especially for an example such as this one, where all
you wind up doing is waiting at checkpoints in one thread for another
thread to finish. That's just silly. If a thread is just waiting on
another thread, it could instead be doing the work that other thread is
doing, saving you a thread.

-- You are doing unnecessary work processing the image file. Just use
FileStream to read it, and send the bytes directly from the file, rather
than doing all that stuff with the Bitmap class.

-- More importantly, I see nothing in the code you posted that would
cause the main thread to wait for the connection to actually be
established before it tries to start sending. I'm surprised you don't get
an exception (if you really don't, maybe there's a subtle bug in .NET),
but in any case you definitely should not call BeginSend() on the socket
until after you've called EndConnect().

Of course, had you just implemented it synchronously, you wouldn't have
made that mistake. :)

Pete
Sep 8 '08 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Niels Johansen | last post by:
Hello, When using the asynchronous read method in the BufferedStream class, , it seems to me that it blocks like the normal synchronous read method. Why is it so? Why does the...
0
by: Richard | last post by:
Hi, I'm suffering a socket race condition - I think. The code works fine at full speed on a single CPU machine. However when I run full speed on a 2 Zeon machine the socket drops data on an...
9
by: Michael Lindsey | last post by:
I need to write a server app to send images to client GUIs that are outside of the server's domain. The client will have the file system path to the image but can not access the file system. I am...
7
by: Colin | last post by:
I'm writing a little console socket server but I'm having some difficulty. Can I ask your advice - where is the best place to get some help on that topic? It would be nice if some people who knew...
2
by: Macca | last post by:
My app has an asynchronous socket server. It will have 20 clients connected to the server. Each client sends data every 500 millisecondsThe Connections once established will not be closed unless...
4
by: Engineerik | last post by:
I am trying to create a socket server which will listen for connections from multiple clients and call subroutines in a Fortran DLL and pass the results back to the client. The asynchronous socket...
6
by: Pat B | last post by:
Hi, I'm writing my own implementation of the Gnutella P2P protocol using C#. I have implemented it using BeginReceive and EndReceive calls so as not to block when waiting for data from the...
5
by: raghubr | last post by:
Hi all, Can any one pls guide me through..I need to transfer the file from server to client and client to server using sockets in an Asynchronous mode so this file transfer doesn't hinder the...
2
by: Nicolas Le Gland | last post by:
Hello everyone here. This is my first post in this newsgroup, I hope I won't be to much off-topic. Feel free to redirect me to any better group. I am getting strange timing issues when...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.