C# Sockets sending random data?

edg3

Well-Known Member
Joined
Jan 10, 2005
Messages
187
Hi there,

Ive been using c# 2008 express edition to experiment with sockets (in this case a TcpServer and a TcpClient) and have gotten the server to communicate with multiple clients, but have run into some weird issues with the sending of data. The data the the server sends to the clients isnt what it should be, for instance, sending a message saying "asd" should give back a single line "127.0.0.1:666 asd" but rather returns two lines, a blank one then the line that it should.

After experimenting with the data sent from the server I decided I would make it use nicks, and all I can say is that was even weirder. I made it so that "NAME {newnamehere}" changed your nick, which works fine, but somehwere along the lines this line:
Code:
string gg = names[i].ToString() + "\n       " + t;
was giving its own weird problems, like cutting off the first handful of characters from t. The same thing happens in a different place in my code where I use the following:
Code:
t = names[i] + "     " + clients[i].Client.LocalEndPoint.ToString();/CODE]
The only thing that seems to sort this issue out is the added spaces.

So I was wondering if anyone has experienced this before? And if possible do you know how to solve this issue or have any suggestions? I would google for any answers but I havent got a clue what I would search for, Ive tried things along the lines of "c# string concatenation overwriting characters"

Here is my code, just please dont comment on the memory leaks I have, I know there are many, Im just focussing on one problem at a time ;)

Server:
[CODE]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 ChatServHost
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        TcpListener tcpServer;
        List<TcpClient> clients = new List<TcpClient>();
        List<NetworkStream> streams = new List<NetworkStream>();
        List<string> names = new List<string>();

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                tcpServer = new TcpListener(666);
                tcpServer.Start();

                timCheckForCon.Enabled = true;
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.GetHashCode().ToString() + "\n" + se.Message);
            }
        }

        public bool pos(string substring, string mainstring)
        {
            string temp = "";
            temp = copy(mainstring, 0, mainstring.Length);
            if (temp.Contains(substring))
            {
                return true;
            }
            return false;
        }
        public string copy(string str, int start, int count)
        {
            string t = "";
            for (int i = start; i < count + start; i++)
            {
                t = t + str[i];
            }
            return t;
        }
        private void timCheckForCon_Tick(object sender, EventArgs e)
        {
            while (tcpServer.Pending())
            {
                try
                {
                    clients.Add(tcpServer.AcceptTcpClient());
                    streams.Add(clients[clients.Count - 1].GetStream());
                    listBox1.Items.Add(clients[clients.Count - 1].Client.LocalEndPoint.ToString());
                    names.Add(clients[clients.Count - 1].Client.LocalEndPoint.ToString());
                }
                catch (SocketException se)
                {
                    listBox1.Items.Add(se.GetHashCode().ToString() + "\n" + se.Message);
                }
                catch (NullReferenceException ne)
                {
                    listBox1.Items.Add(ne.GetHashCode().ToString() + "\n" + ne.Message);
                }
            }
            for (int i = 0; i < clients.Count; i++)
            {
                try
                {
                    if (streams[i].DataAvailable)
                    {
                        byte[] b = new byte[255];
                        streams[i].Read(b, 0, 255);
                        streams[i].Flush();
                        string s = System.Text.ASCIIEncoding.ASCII.GetString(b);
                        listBox1.Items.Add(s);
                        string t = "";
                        t = copy(s, 0, s.Length);

                        if (pos("NAME", s))
                        {
                            t = names[i] + "     " + clients[i].Client.LocalEndPoint.ToString();
                            names[i] = copy(s, 4, s.Length - 5);
                        }

                        for (int g = 0; g < clients.Count; g++)
                        {
                            string gg = names[i].ToString() + "\n       " + t;
                            b = System.Text.ASCIIEncoding.ASCII.GetBytes(gg);
                            streams[g].Write(b, 0, gg.Length);

                        }
                    }
                }
                catch (SocketException se)
                {
                    listBox1.Items.Add(se.GetHashCode().ToString() + "\n" + se.Message);
                }
                catch (NullReferenceException ne)
                {
                    listBox1.Items.Add(ne.GetHashCode().ToString() + "\n" + ne.Message);
                }
                catch (IOException ie)
                {
                    listBox1.Items.Add(ie.GetHashCode().ToString() + "\n" + ie.Message);
                }
            }
            }
        }
    }

Client:
Code:
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 ChatServClient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        TcpClient tcpClient;
        NetworkStream s;

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                IPAddress ad = IPAddress.Parse(comboBox1.Text);
                tcpClient = new TcpClient();
                tcpClient.Connect(ad, 666);
                listBox1.Items.Add("Connected " + tcpClient.Connected.ToString());
                s = tcpClient.GetStream();

                timer1.Enabled = true;
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.GetHashCode().ToString() + "\n" + se.Message);
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] b;
                b = System.Text.ASCIIEncoding.ASCII.GetBytes(textBox2.Text);
                s.Flush();
                s.Write(b, 0, textBox2.Text.Length);
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.GetHashCode().ToString() + "\n" + se.Message);
            }
            catch (IOException ie)
            {
                MessageBox.Show(ie.GetHashCode().ToString() + "\n" + ie.Message);
            }
            catch (NullReferenceException nr)
            {
                listBox1.Items.Add(nr.Message + "\n");
            }
            textBox2.Clear();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                if (s.DataAvailable)
                {

                    byte[] b = new byte[255];
                    s.Read(b, 0, 255);
                    s.Flush();
                    string st = System.Text.ASCIIEncoding.ASCII.GetString(b);
                    st.Replace("\n"[0], "\0"[0]);
                    st.Replace("\r"[0], "\0"[0]);
                    if ((st != null) && (st != ""))
                    {
                        listBox1.Items.Add(st);
                    }
                }
            }
            catch (SocketException se)
            {
                MessageBox.Show(se.GetHashCode().ToString() + "\n" + se.Message);
                timer1.Enabled = false;
            }
            catch (NullReferenceException nr)
            {
                listBox1.Items.Add(nr.Message + "\n");
            }

            listBox1.SelectedIndex = listBox1.Items.Count - 1;

        }

        private void textBox2_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                try
                {
                    byte[] b;
                    b = System.Text.ASCIIEncoding.ASCII.GetBytes(textBox2.Text);
                    s.Flush();
                    s.Write(b, 0, textBox2.Text.Length);
                }
                catch (SocketException se)
                {
                    MessageBox.Show(se.GetHashCode().ToString() + "\n" + se.Message);
                }
                catch (IOException ie)
                {
                    MessageBox.Show(ie.GetHashCode().ToString() + "\n" + ie.Message);
                }
                catch (NullReferenceException nr)
                {
                    listBox1.Items.Add(nr.Message + "\n");
                }
                textBox2.Clear();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Items.Add("127.0.0.1");
            comboBox1.Items.Add("192.168.1.10");
        }

    }
}

If you want I can give you the compiled programs for you to try out yourself and see what I mean.
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
Had a very quick look at your code.

I think some of the problems you are having is because you are using the NetworkStream's of the TcpClient. You've got Flush's and Writes all over the place, which is probably causing you trouble.

Rather use the Socket to communicate like this to send: TcpClient.Client.Send(parameters)

And this to recieve:
if (TcpClient.Client.Available > 0)
{
byte[] buffer = TcpClient.Client.Recieve()
.. whatever
}

Much easier. Once you got the hang of it I suggest Asynchronous Sockets for a chat application and toss all the timers.
 

edg3

Well-Known Member
Joined
Jan 10, 2005
Messages
187
I think some of the problems you are having is because you are using the NetworkStream's of the TcpClient. You've got Flush's and Writes all over the place, which is probably causing you trouble.
Searching around on the net it seemed that that was the way do things, but I'll make the changes you suggested (except the asynchronous part which I havent gotten my head around yet). Thanks
 

dequadin

Expert Member
Joined
May 9, 2008
Messages
1,434
Searching around on the net it seemed that that was the way do things, but I'll make the changes you suggested (except the asynchronous part which I havent gotten my head around yet). Thanks

There is nothing wrong with using network streams, if you look at this article on codeproject you'll see they use it. The main reason I can see you using them is that NetworkStream.Read is not blocking however you should then always do stuff like int numBytes = NetworkStream.Read(...); which I see you don't do. You can get around the TcpClient.Client.Read(..) blocking problem by first checking TcpClient.Client.Available before reading the socket.

I just think for what you want to do reading and writing to the socket for you first network application is by far the easiest method.
 
Top