Jump to content
blackfriday

C# chat, Open new Chat window (Like popup) on LAN

Recommended Posts

Posted

I am trying to make a C# Chat.

 

So far i have been able to work on getting the 2 clients to work together and send notification using the notifyicon. now What i want to achieve is something done by yahoo messenger. If i am online and dont have a messenger window on (if i am not talking to anyone) and someone sends me a message on LAN, I should be able to receive a new Message window.

 

My code looks like this :

 

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.Net.Sockets;
using System.Net;

namespace ChatTestNowx
{
    public partial class Form1 : Form
    {
        Socket sock;
        EndPoint epLocal, epRemote;
        byte[] buffer;
        public Form1()
        {
            InitializeComponent();
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

            pc1IP.Text = GetLocalIP();
            Pc2IP.Text = GetLocalIP();

           Message.KeyDown += new KeyEventHandler(MyKeyDownFunction); // Event to open new chat window on PC
        }

        //Message.KeyDown += new KeyEventHandler(MyKeyDownFunction);
        private void MyKeyDownFunction(object sender, KeyEventArgs e)
        {
            // Open new Chat window and show chat information
        }

        private void MessageCallBack(IAsyncResult aResult)
        {
            try
            {
                byte[] receivedData = new byte[1500];
                receivedData = (byte[])aResult.AsyncState;
                ASCIIEncoding asc = new ASCIIEncoding();
                string recievedMsg = asc.GetString(receivedData);
                listMessage.Items.Add("Friend:" + recievedMsg);

                buffer = new byte[1500];
                sock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void send_btn_Click(object sender, EventArgs e)
        {
            ASCIIEncoding aec = new ASCIIEncoding();
            byte[] sendingMessage = new byte[1500];
            sendingMessage = aec.GetBytes(Message.Text);
            sock.Send(sendingMessage);
           listMessage.Items.Add("Me :" + Message.Text);
            Message.Text = "";
        }


        private string GetLocalIP()
        {
            IPHostEntry host;
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    return ip.ToString();
                }
            }
            return "127.0.0.1";
        }

        private void Message_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                //this.WindowState = FormWindowState.Normal;
                ASCIIEncoding aec = new ASCIIEncoding();
                byte[] sendingMessage = new byte[1500];
                sendingMessage = aec.GetBytes(Message.Text);
                sock.Send(sendingMessage);
                listMessage.Items.Add("Me :" + Message.Text);
                Message.Text = "";
            }
        }

        private void connect_btn_Click(object sender, EventArgs e)
        {
            epLocal = new IPEndPoint(IPAddress.Parse(pc1IP.Text), Convert.ToInt32(pc1Port.Text));
            sock.Bind(epLocal);

            epRemote = new IPEndPoint(IPAddress.Parse(Pc2IP.Text), Convert.ToInt32(Pc2Port.Text));
            sock.Connect(epRemote);

            buffer = new byte[1500];

            sock.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageCallBack), buffer);
            connect_btn.Text = "&Connected!";
            connect_btn.Enabled = false;
        }
    }
}

What i have tried so far, I created events. And wanted to use this event only it does not work as i expected

 

i added this and it does not work as i expected , hence i had to take it out.

 

            if (e.KeyCode == Keys.Enter)
            {
                Form1 frm = new Form1();
                frm.Show();
                ASCIIEncoding aec = new ASCIIEncoding();
                byte[] sendingMessage = new byte[1500];
                sendingMessage = aec.GetBytes(Message.Text);
                //sock.Send(sendingMessage);
                listMessage.Items.Add("Me :" + Message.Text);
                Message.Text = "";
            }

 

Posted

At a first glance at your code, you have some logic issues:

  • the code you removed because it does not behave like you expected attempt to create a new instance of Form1 which is essentially itself (including all the socket stuff)
  • the above mentioned code is supposed to be run on an <ENTER> key press, and display the received message in a new window, but that's not how events work: you need to define an event for when you receive the message and then check if you have a window for that client/person/nick/etc and if you don't, pop up a new one
  • you use Yahoo Messenger as an example, but Yahoo Messenger was using a client (the aforementioned Yahoo Messenger) and a server (the Yahoo servers); your applications seems to be IP to IP UDP so you have to adjust accordingly

Also in my opinion, it's a bad idea to have the network stuff in the GUI thread.

 

My first suggestion would be to first define a communication protocol: a way to serialize data so you have an easy way to determine what goes where. This also covers message receiving signaling since you are using UDP.

 

Now depending on what you want to achieve, you could go several ways as far as implementation goes:

  • If you want to keep it as a p2p application, the simplest solution is to open a new application instance for each ip-port tuple (meaning for each client designated by an IP:Port combination you will launch an instance of the application)
  • If you would like to allow for things such as a discussion channel or conference channel or what ever you want to call it: a way for your message to be received by more than one person without sending it to everyone, you could use IP Broadcast or IP Multicast. And for private messages you could either tell the application to disregard the messages if it's not meant for them or have the protocol open a private connection using the individual IP addresses.
  • If you want to replicate the Yahoo Messenger "architecture" you would make two applications: one would be a server and one would be a client

 

If I will have time I will try to make you a small demo.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...