[.net] Problems with writing data in C#

Started by
7 comments, last by Afr0m@n 18 years, 1 month ago
I've written myself a lil' ASCII writer singleton for writing data over the network. However, it doesn't seem to work, because nothing's picked up at the other side. Is the problem in this singleton?
/*
 * Created by SharpDevelop.
 * User: Mats Vederhus
 * Date: 14.02.2003
 * Time: 16:51
 */

using System;
using System.Net.Sockets;
using System.Text;

namespace IOCP_Server
{
	/// <summary>
	/// A singleton class that contains functions for writing ASCII
	/// data to a socket.
	/// </summary>
	public sealed class ASCIIWriter
	{
		private static ASCIIWriter instance = new ASCIIWriter();
        private byte[] DataArray;
		
		public static ASCIIWriter Instance 
		{
			get {
				return instance;
			}
		}
		
		private ASCIIWriter()
		{
		}
		
		public void WriteLine(Socket SocketHandle, string Data)
		{
			DataArray = new byte[Data.Length];
			DataArray = Encoding.ASCII.GetBytes(Data.ToCharArray());
			
            //May have to change 100 to something else later on...
			SocketHandle.BeginSend(DataArray, 0, DataArray.Length, SocketFlags.None, new AsyncCallback(WriteCallback), SocketHandle);
			int Sent = SocketHandle.Send(DataArray, 0, DataArray.Length, SocketFlags.None);
			System.Windows.Forms.MessageBox.Show("Bytes sent with Send(): " + Sent);
		}
		
		private void WriteCallback(IAsyncResult ar)
		{
			Socket s = (Socket)ar.AsyncState;
			int BytesSent = s.EndSend(ar);
			System.Windows.Forms.MessageBox.Show("Bytes sent: " + BytesSent);
			//s.BeginSend(DataArray, 0, DataArray.Length, SocketFlags.None, new AsyncCallback(WriteCallback), s);
			s.Close();
		}
	}
}


_______________________Afr0Games
Advertisement
If you're calling BeginSend, the next line should be int sent = EndSend(). That's the only thing I can see that is wrong, although the first assignment to DataArray is a waste of time as you're reassigning it immediately below.

Edit: EndSend() doesn't take any parameters. It just tells .Net to finish sending whatever you started in BeginSend(). The data should be sent shortly after the call to BeginSend whether you call EndSend or not, though.

Simple questions – does the socket connect? Are you sending data to the right socket? etc.
you aren't flushing the stream. You need to flush the stream before anything will actually be sent.

[Formerly "capn_midnight". See some of my projects. Find me on twitter tumblr G+ Github.]

Thanks guys!

What I don't understand though, is - I don't have a network stream! Should I create one and then flush it? That ddoesn't make much sense. Should I write directly to the stream? Please explain.
_______________________Afr0Games
Send (and therefore presumably BeginSend/EndSend) work for me without explicit flushing.
Ok, changed my source a little:

/* * Created by SharpDevelop. * User: Mats Vederhus * Date: 14.02.2003 * Time: 16:51 */using System;using System.Net.Sockets;using System.Text;namespace IOCP_Server{	/// <summary>	/// A singleton class that contains functions for writing ASCII	/// data to a socket.	/// </summary>	public sealed class ASCIIWriter	{		private static ASCIIWriter instance = new ASCIIWriter();        private byte[] DataArray;        private NetworkStream Stream;				public static ASCIIWriter Instance 		{			get {				return instance;			}		}				private ASCIIWriter()		{		}				public void WriteLine(Socket SocketHandle, string Data)		{			DataArray = new byte[Data.Length];			DataArray = Encoding.ASCII.GetBytes(Data.ToCharArray());            Stream = new NetworkStream(SocketHandle);			            //May have to change 100 to something else later on...			SocketHandle.BeginSend(DataArray, 0, DataArray.Length, SocketFlags.None, new AsyncCallback(WriteCallback), SocketHandle);            Stream.BeginWrite(DataArray, 0, DataArray.Length, new AsyncCallback(WriteCallback), Stream);		}				private void WriteCallback(IAsyncResult ar)		{			Socket s = (Socket)ar.AsyncState;			int BytesSent = s.EndSend(ar);			System.Windows.Forms.MessageBox.Show("Bytes sent: " + BytesSent);            Stream.Flush();			s.Close();		}	}}


Seems I can't create a stream with an async socket because I get an exception on this line:

"Stream = new NetworkStream(SocketHandle);"

It says that it can't do that with a non blocking socket.

Anyway I think that there's something wrong with this class because I've made a test client in C# (original client written in Blitz Max), and I used the exact same class for writing to this server. But it doesn't pick up anything, and I know it's supposed to because it does when the Blitz Max client writes to it.

Anyone?


_______________________Afr0Games
bump
_______________________Afr0Games
Umm, ok... let's take the first code...

Why are you using BeginSend/EndSend() at all? Lose them. They're only needed for sending in a separate thread, which is not what you would usually want to do with a small utility class like this.

It is correct, however. Both your Send() and BeginSend()/EndSend() should work.

But still, just do a single SocketHandle.Send(DataArray, 0, DataArray.Length);

If that does not throw an exception, it works fine and the problem is with the receiving end. (Assuming the socket was set up properly, no firewall is screwing stuff up and the network is not hosed and Winsock has not turned into a potato)






Also, more flaws:
1) Data.Length is not the length of the string in bytes, so why are you using it as a byte counter? Don't.
2) You don't need to initialize DataArray, GetBytes() returns a new one already.
3) ToCharArray() is unnecessary (and I wonder if it might be messing up the string conversion? Probably not, but maybe)
Dude thanks that worked. :) Turned out the problem was on the server and client side.
_______________________Afr0Games

This topic is closed to new replies.

Advertisement