I have problem with receiving an image over TCP socket [.net 4.0]
Server:
Socket s = null;
Socket client;
private void button1_Click(object sender, EventArgs e)
{
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Any, 9988));
s.Listen(1);
client = s.Accept();
pictureBox1.Image = Image.FromStream(new NetworkStream(client));
//Server freezes here and waiting for the image .. but in the Client side.. it tells that it sent.
Console.WriteLine("Received.");
}
Client:
Socket s = null;
private void button1_Click(object sender, EventArgs e)
{
s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9988));
Rectangle bounds = Screen.GetBounds(Point.Empty);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
bitmap.Save(new NetworkStream(s), ImageFormat.Png);
Console.WriteLine("sent.");
}
Edit:
im making a big application .. image was receiving just fine .. then i did some changes on the code so it got complicated to know what did i exactly change .. now it's not working .. so i made new projects and tried the code up.. still doesn't work .. i know that there's another ways to do it.. but i prefer to do this way.
Anyone knows how to fix it ??
i think you need to convert the image to byte and then get the byte's size and send it to the server, the server prepares the buffer size and then the client send the image's bytes, you can find s video on how to do it Right Here
Most probably you need to close the socket after sending the data.
Image.FromStream() probably waits until the NetworkStream indicates there are no more bytes to process, but since you declared the Socket on the form's class level, it stays connected and the server waits for more data.
Related
I am trying to develop an video chat application via UDP C#. I have an picture box that shows the webcam of the user continuously and sending to a specific port. But I don't know how to receive the Image
I am using a byte to image / image to byte converter class (which normally works fine) but when I put this code in a timer sequence I get this error
'A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself'
here is my code :
private void timer1_Tick(object sender, EventArgs e)
{
Image bitmap = pictureBox1.Image;
byte[] sndcam = imageToByteArray(bitmap);
string Ip = "127.0.0.1";
int port = 1111;
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(Ip), port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.SendTo(sndcam, ep);
}
I've seen few questions like this on Stackoverflow but I cloudn't find a satisfying answer
Should I use RTP instead ? If so , How ?
Thanks in advance
How to send JPG over TCP from one Windows Phone to another?
I found that in the other SO topic(below) showing how to send text over TCP, but how to turn JPG to bytes and send it? Most of jpges are bigger than 4kb how to deal with that?:
private void sendMessage() {
connectArgs = new SocketAsyncEventArgs { RemoteEndPoint = new DnsEndPoint(localIP, Int32.Parse(port)) };
connectArgs.Completed += connectArgs_Completed;
connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connection.ConnectAsync(connectArgs);
}
void connectArgs_Completed(object sender, SocketAsyncEventArgs e) {
if (e.SocketError == SocketError.Success && firstLoop) {
firstLoop = false;
var sendArgs = new SocketAsyncEventArgs();
var buffer = Encoding.UTF8.GetBytes("MESSAGE STRING" + Environment.NewLine);
sendArgs.SetBuffer(buffer, 0, buffer.Length);
sendArgs.Completed += sendArgs_Completed;
e.ConnectSocket.SendAsync(sendArgs);
} else {
//blad
}
}
You should probably read the raw image data and send that, along with a special "code" or prefix, and then on the receiving end, save the raw image data to a .jpg file and display that. You can do that with any file.
TCP doesn't limit the size of the packets to 4KB, so that shouldn't be a problem for you. You simply need to read all the image bytes either from file using File.ReadAllBytes or a stream reader, and you then send those bytes across to the receiver.
Alternatively, if you have the image as an object, you could use Marshal.StructureToPtr on the sending end and then use Marshal.PtrToStructure to re-create the image object from the bytes you have received, if you want to show the image directly for example.
I am writting a C# P2P Video Chat (Part of my exam on Faculty),a i am little stuck at send Data via udp. So here how it works. I have a Web_Capture library, and every time image is captured it sets PictureBox image to the captured one
private void webCamCapture_ImageCaptured(object source, WebCam_Capture.WebcamEventArgs e)
{
myCamera.Image = e.WebCamImage;
sendData(ref ipep2); // send it immediately
}
So then the sendData method starts sending...
private void sendData(ref IPEndPoint sender)
{
byte[] data;
if (friendsClient == null)
{
friendsClient = new UdpClient();
}
MemoryStream myStream = new MemoryStream();
myCamera.Image.Save(myStream, System.Drawing.Imaging.ImageFormat.Jpeg);
data = myStream.GetBuffer();
friendsClient.Send(data, data.Length,sender);
}
When i debug, the socket exception pops out:
System.Net.Sockets.SocketException was unhandled by user code
Message=The requested address is not valid in its context
Source=System
ErrorCode=10049
NativeErrorCode=10049
So, does anyone have any idea, i will be thankfull if he support that idea with code, because i am nooby at c# :) thanks in advance. Marjan
You should specify reciever's ip and port, Here is a complete example
so you should change your implementation to
private void sendData(ref IPEndPoint reciever)
{
byte[] data;
Socket sending_socket = new Socket(AddressFamily.InterNetwork, ocketType.Dgram, ProtocolType.Udp);
MemoryStream myStream = new MemoryStream();
myCamera.Image.Save(myStream, System.Drawing.Imaging.ImageFormat.Jpeg);
data = myStream.GetBuffer();
sending_socket.SendTo(data, reciever);
}
I have been struggling for a while now to send an image file over sockets. I believe I am very close, but I haven't gotten it yet. I am trying to send the image from the server to the client.
Here is my server code:
//Init listener
listener = new TcpListener(new IPEndPoint(IPAddress.Any, 550));
//Start listening for connections
listener.Start();
Console.WriteLine("Waiting for connection");
s = listener.AcceptSocket();
//If we reach here, we have a connection
Console.WriteLine("Connected");
//Get the screenshot and apply it to our memory stream
img = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
imgG = Graphics.FromImage(img);
imgG.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
ms = new MemoryStream();
img.Save(ms, ImageFormat.Jpeg);
img.Save("sc.jpg", ImageFormat.Jpeg);
//Convert image to byte array, and then send it
byte[] byteArray = ms.ToArray();
s.Send(byteArray);
s.Close();
Console.Read();
Here is my client code:
client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Parse(IPBox.Text), 550));
s = client.Client;
buffer = new byte[100000];
s.Receive(buffer);
ms.Read(buffer, 0, 100000);
img = (Bitmap)Image.FromStream(ms);
imgContainer.Image = (Image)img;
I think I am very close, but I might be far off. I am new to networking, and require help please. Thanks A lot.
The problem is that in your client, you are assuming that you received 100000 bytes from the server, and you're putting all 100000 bytes into the memory stream.
There is a great sample on the MSDN page for TcpClient which shows receiving from a TcpClient by using the underlying NetworkStream. Also, you will want to keep track of how many bytes you actually received (this is the return value from the NetworkStream.Read function). Finally, you'll want to keep reading until there is no more data to be read from the host. If your image is larger than your buffer, then you'll only have a partial image also. The sample on the linked page for NetworkStream.Read shows continually reading from the stream while there is data available.
I have this method which i use to send a Transfer object
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Any, 7777);
Socket sockListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sockListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
sockListener.Bind(ipEnd);
sockListener.Listen(100);
s = sockListener.Accept();
private void sendToClient(Transfer.Transfer tt)
{
byte[] buffer = new byte[15000];
IFormatter f = new BinaryFormatter();
Stream stream = new MemoryStream(buffer);
f.Serialize(stream, tt);
Console.WriteLine("1/3 serialized");
stream.Flush();
Console.WriteLine("2/3 flushed stream");
s.Send(buffer, buffer.Length, 0);
Console.WriteLine("3/3 send to client");
}
The strange thing is it work the first 2 times i call it, then on the 3rd call it hangs on s.send().
Its the same if i want to send String instead of Transfer.
The comment by #nos is probably correct, the TCP Send buffer is probably filling up and the 3rd call to s.send() is blocking until the data is sent over the network. You can set the used buffer sizes like this:
Socket s = sockListener.Accept();
s.ReceiveBufferSize = 1024 * 64;
s.SendBufferSize = 1024 * 64;
You should be able to confirm your problem by setting your buffer sizes to a larger multiple of the size of data you're sending.
Also, as suggested, you should check the client to make sure its reading the data properly.