Click here to Skip to main content
Email Password   helpLost your password?

Sample Image - PictureChat2.JPG.

1.0 Introduction

Most chat programs are text based, and do not support multi languages. In this article, I would like to share with the reader, the techniques I used to implement multilingual support and picture/media transfer in a chat program.

2.0 Streams and Protocols

A stream is a continuous flow of bytes. For a chat server and a chat client to communicate over the network, each would read and write to the network stream. The network stream is duplex, and bytes transmitted and read are always in FIFO order.

When a chat client is connected to a chat server, they would have established a common network stream to use.

However, for any meaningful communication, there must be some rules and order. These rules and order would be known as the communication protocols. There are at least a few layers of protocols.

At the lowest level, the communicating parties would need to know how to break a continuous flow of bytes into packets/frames. These rules would be referred to as the Network Protocol.

At the next level, the parties would need to interpret the packets/frames. These rules would be known as the Application Protocol(s).

3.0 Network Protocol

I would like to make a distinction between a text stream and a binary stream. In a text stream, only text characters are allowed. In a binary stream, all byte values (0x00 - 0xFF) are allowed.

One way to set markers in a text stream is to use a non-text byte as a marker. For example, the traditional C string is terminated by 0x00, which serves as an end marker.

For a binary stream, there is no way to set a marker because all byte values are legal. Thus, one way to break a binary stream to packets is for the parties to communicate to one another about the size of the binary bytes to follow, before actually sending the bytes.

In ChatStream.cs, the ChatStream class is implemented with methods for reading and writing text data (Read() and Write()), and also methods for reading and writing binary data (ReadBinary() and WriteBinary()).

Note that in the Write() method, we set a 0x03 as the marker, and Read() will read until the marker is encountered. For the WriteBinary() method, no marker is set, and ReadBinary() requires an input parameter to indicate the number of bytes to read.

public class ChatStream:IChatStream 
{
 //..
 public string Read(NetworkStream n)
 {
   //maximum buffer size is 256 double byte character
   byte[] bytes=new byte[512];
   //total number of bytes read
   int totalbytes=0;
   while(true){
     //reading 2 byte at a time
     int i=n.Read(bytes,totalbytes,2);

     //small endian first byte is lsb
     if(i==2)
     {
       //the special end byte if found
       if(bytes[totalbytes]==(byte)0x03)
         if(bytes[totalbytes+1]==(byte)0x00)
           break;
     }
     else
     {
       //end of stream
       return "";
     }
     //advance to the next position to store read byte(s)
     totalbytes +=i;
   }

   //convert the bytes to a unicode string and return
   UnicodeEncoding Unicode = new UnicodeEncoding();
   int charCount = Unicode.GetCharCount(bytes, 0, totalbytes);
   char[] chars = new Char[charCount];
   Unicode.GetChars(bytes, 0, totalbytes, chars, 0);
   string s=new string(chars);
   return s;
 }

 public void Write(NetworkStream n,string s)
 {
   //Append char 0x03 to end of text string
   s=s+new string((char)0x03,1);
   //byte[] bytes=System.Text.Encoding.ASCII.GetBytes(s);
   UnicodeEncoding Unicode = new UnicodeEncoding();
   byte[] bytes=Unicode.GetBytes(s);
   n.Write(bytes,0,bytes.Length );
   n.Flush();
 }

 public byte[] ReadBinary(NetworkStream n,int numbytes)
 {
   //total bytes read
   int totalbytes=0;

   byte[] readbytes=new byte[numbytes];

   while(totalbytes<numbytes)
   {
     //read as much as possible
     int i=n.Read(readbytes,totalbytes,numbytes-totalbytes);

     //End of stream
     if(i==0)
        return null;

     //advence to the next position to store read byte(s)
     totalbytes +=i;
   }
   return readbytes;
 }

 public void WriteBinary(NetworkStream n,byte[] b)
 {
   n.Write(b,0,b.Length);
   n.Flush();
 }
}

4.0 Unicode

The traditional C string is a single-byte character string. It is adequate for representing all ASCII characters. However, for languages where the character set has more than 256 characters, a single-byte character representation is no longer adequate.

In .NET as in VB, strings are all internally double-byte.

To manipulate the double-byte characters in the String class, we can make use of the UnicodeEncoding class.

This code fragment shows how to extract out all the double-byte bytes from a string:

UnicodeEncoding Unicode = new UnicodeEncoding();
byte[] bytes=Unicode.GetBytes(s);

Similarly, to construct a Unicode string from a byte array:

UnicodeEncoding Unicode = new UnicodeEncoding();
int charCount = Unicode.GetCharCount(bytes, 0, totalbytes);
char[] chars = new Char[charCount];
Unicode.GetChars(bytes, 0, totalbytes, chars, 0);
string s=new string(chars);

Although the TextBox and RichTextBox controls in .NET support Unicode, a Unicode supported font is needed for display of Unicode characters, and an appropriate IME (Input Method Editor) is needed for Unicode input.

For this program, I make use of Arial Unicode MS which comes with Windows XP.

5.0 Sending and Receiving Pictures

If you ever use a binary editor to view a picture file (JPG or BMP), you will know that all byte values are possible in a picture file. To transfer picture binary data from a file or memory stream, we would not be able to set a marker to break the stream as what we can do for text data.

For this program:

The protocol for sending a picture is as follows:

The protocol for getting a picture is as follows:

The server code for acting on the send_pic and get_pic commands from the client:

//SEND PIC
private void action_send_pic()
{
  string[] s=readdata.Split(':');
  string name="";
  //format is
  //:send pic:<target>
  if (s.Length==3)name=s[2];

  //Locate the target
  TcpClient t=null;
  if (chatserver.FindUserRoom(name)!=0)
    t=(TcpClient)chatserver.ClientConnections[name.ToUpper()];

  //If target is found
  if((t!=null))
  {
    //Inform the sender(client) to send the picture
    chatserver.Write(client.GetStream(), 
                  ChatProtocolValues.SEND_PIC_MSG);

    //Find out the number of byte to read from sender
    string snumbytes=chatserver.Read(client.GetStream());
    int numbytes=int.Parse(snumbytes);

    //read the bytes
    byte[] b=chatserver.ReadBinary(client.GetStream(),numbytes);
    if (b==null)
    {
      chatserver.Write(client.GetStream(),
         "server> Transmission Error");
      return;
    }

    //To store the data in a jpg file
    //name convention is <sender>_<target>.jpg
    FileStream f=new FileStream(nickname+"_"+name+".jpg",FileMode.Create);
    f.Write(b,0,b.Length);
    f.Close();
    //Inform the target that there is a picture from sender
    chatserver.Write (t.GetStream(),
      ChatProtocolValues.PIC_FROM_MSG(nickname,name));
    //Inform the sender that server had received the picture
    chatserver.Write(client.GetStream(),
       ChatProtocolValues.PIC_SEND_MSG(nickname));
  }
  else
  {
    //If target is not found inform sender
    chatserver.Write(client.GetStream(),
      ChatProtocolValues.USER_NOT_FOUND_MSG(name));
  }
}

//GET PIC
private void action_get_pic()
{
  string[] s=readdata.Split(':');
  string sender="";
  string picname="";
  //format is
  //:get pic:<sender>
  if(s.Length==3)sender=s[2];

  //format of saved jpg file is
  //<sender>_<target>.jpg
  //In this case the current user is the target
  picname=sender + "_" + nickname + ".jpg";

  //Check for existence of file
  if(!File.Exists(picname))
    chatserver.Write(client.GetStream(),
      ChatProtocolValues.PIC_NOT_FOUND_MSG(picname));
  else
  {
    //Create a file stream
    FileStream f=new FileStream(picname,FileMode.Open);
    //To get the size of the file for purpose of memory allocation
    FileInfo fi=new FileInfo(picname);
    byte[] b=new byte[fi.Length];
    //Read the content of the file and close
    f.Read(b,0,b.Length);
    f.Close();
    //Inform the client to get the pic
    chatserver.Write (client.GetStream(),
      ChatProtocolValues.GET_PIC_MSG);
    //Inform the client of number of bytes
    chatserver.Write(client.GetStream(),""+b.Length);
    //Send the binary data
    chatserver.WriteBinary(client.GetStream(),b);
    //Inform the client that all binary data has been send
    chatserver.Write(client.GetStream(),
      ChatProtocolValues.PIC_SEND_ACK_MSG);

    //Locate the sender of the picture
    TcpClient t=null;
    if (chatserver.FindUserRoom(sender)!=0)
      t=(TcpClient)chatserver.ClientConnections[sender.ToUpper()];

    //Inform the sender that the target has gotten the picture
    if(t!=null)
      chatserver.Write(t.GetStream(),
        ChatProtocolValues.GOTTEN_PIC_MSG(nickname));
  }
}

The client responses to the server's messages:

//SEND PIC
//Sending picture to the server
private void action_server_send_pic()
{
  //Console.WriteLine("server> send pic");
  //Save the picture box image to the memory
  MemoryStream ms=new MemoryStream();
  pic.Image.Save(ms,ImageFormat.Jpeg);
  //Get the memory buffer
  byte[] buf=ms.GetBuffer();
  ms.Close();

  Write("" + buf.Length);
  //Thread.Sleep(500);
  WriteBinary(buf);

  Console.WriteLine("Send: {0} bytes", buf.Length);
}

//GET PIC
//Geting picture from server
private void action_server_get_pic()
{
  string snumbytes=Read();
  int numbytes=int.Parse(snumbytes);
  //int numbytes=0;
  byte[] readbytes=ReadBinary(numbytes);

  if(readbytes==null)
  {
    Console.WriteLine("Error getting picture");
    responseData="server> Error getting picture";
    action_message();
    return;
  }

  //Create the image from memory
  MemoryStream ms=new MemoryStream(readbytes);
  Image img=Image.FromStream(ms);
  ms.Close();

  //Paste picture to the rich text box
  PastePictureToRTB(img);
}

6.0 Sending, Receiving, and Playing Media Clips

The protocol for transferring media clips is very similar to that for picture transfer. The main difference is that unlike a picture which is basically copied from a picture box in the UI and saved to a file with a fixed jpg extension, the media clips are just files that are tagged and stored by the program, and can have various different extensions. The extension for these files has to be maintained as the media player relies on the extension to play the files.

When sending the binary data of a media clip to the server, the extension of the clip must be conveyed. And when the receiver retrieves the binary data from the server, the extension must also be made known so that the media clip file can be recreated with the correct extension.

To resolve this problem, there is a slight change in the protocol. When sending media clip data to the server, the sender first sends a three-character extension, followed by the number of bytes of binary data, and then finally, the binary data. The server first reads the extension, saves the extension to a file named <sender>_<target> (without the extension), and then saves the binary data to a file named <sender>_<target>.<ext>.

private void action_server_send_media()
{
    //To store the data in a media file
    //name convention is <sender>_<target>.ext
    
    if(shp1.Text.Equals("Empty")){
       Write(""+0);
       return;
    }

       String ext=shp1.Text.Substring(shp1.Text.Length-3);
    Write(ext);

    FileInfo fi=new FileInfo(_currentpath +"\\"+nickname+"."+ext);
    FileStream f=new FileStream(_currentpath  +"\\"+nickname+"."+ext,
    FileMode.Open);
    byte[] b=new byte[fi.Length];

    f.Read(b,0,b.Length);
    f.Close();
    Write("" + b.Length);
    //Thread.Sleep(500);
    WriteBinary(b);
    //Console.WriteLine("Send: {0} bytes", b.Length);
}

Similarly, when the receiver retrieves the media clip, the server first locates the file that stores the extension, retrieves the extension, and the retrieves the file <sender>_<target>.<ext>, and then sends the extension followed by the media clip binary data to the receiver.

private void action_server_get_media()
{
    string ext=Read();

    string snumbytes=Read();
    int numbytes=int.Parse(snumbytes);
    //int numbytes=0;
    byte[] readbytes=ReadBinary(numbytes);
    
    if(readbytes==null)
    {
        //Console.WriteLine("Error getting picture");
        responseData="server> Error getting picture";
        action_message();
        return;
    }

    FileStream f=new FileStream(_currentpath + 
        "\\"+nickname+"_received."+ext,
        FileMode.Create);
    f.Write(readbytes,0,numbytes);
    f.Close();

    // shpR.Text=""+(numbytes/1000)+"KB";

    rtb.SelectionStart=rtb.Text.Length;
    _media_id++;

    string c_currentpath=_currentpath.Replace(" ","@");

    rtb.SelectedText="\nfile:///" + c_currentpath + 
        "\\"+nickname+"_received" +
        _media_id+"."+ext;

    File.Copy(_currentpath +"\\"+nickname+"_received."+ext,
    _currentpath +"\\"+nickname+"_received" + 
    _media_id+"."+ext,true);

}

To play the media clip, the system must have the media player installed. The chat client locates the media player from the Windows registry and sends the clip to be played by the media player.

public class WinMediaPlayer
{
    public static string GetMediaPlayerDirectory()
    {

        try
        {
            Microsoft.Win32.RegistryKey localmachineregkey=
                Microsoft.Win32.Registry.LocalMachine;
            Microsoft.Win32.RegistryKey mediaplayerkey=
                localmachineregkey.OpenSubKey(@"SOFTWARE\Microsoft\MediaPlayer");
            return (string)mediaplayerkey.GetValue("Installation Directory");
        }
        catch
        {
           return "";
        }
    }

    public static void Play(IntPtr hwnd,string strFileName)
    {
      if(!ChatClient.MediaPlayerDirectory.Equals(""))
        Helpers.ShellExecute(hwnd,"open","wmplayer",
                "\""+strFileName+"\"",ChatClient.MediaPlayerDirectory ,
                Helpers.SW_NORMAL);
    }
}

7.0 Server Program

The server program starts by creating the requested number of chat rooms, and reads out the users by deserializing the users.bin file. Then, it continues to listen for connections. Once a connection is established, it sprouts a new SocketHelper object to manage the communication with the connected client.

public class ChatServer:ChatStream,IChatServer
{
  //...
  //2 parameters Constructor
  public ChatServer(int port_no,int num_room)
  {
    this.port_no =port_no;
    this.num_room=num_room;

    //init num per room used for room assignment
    num_per_room=DEFAULT_NUM_PER_ROOM;

    //instantiate the connection listener
    listener=new TcpListener(IPAddress.Any,this.port_no);

    //get all the registered users from file
    DeserializeChatUsers("users.bin");

    //init all the rooms
    roomusers=new Hashtable[num_room];
    for(int i=0;i<num_room;i++)
      roomusers[i]=new Hashtable();

    //init connections
    connections=new Hashtable();

    //start listening for connection
    Listener.Start();

    //Loop forever
    //The only way to break is to use clt break key
    while(true)
    {
      Console.WriteLine("Waiting for connection...");
      //get the connected client
      TcpClient client=Listener.AcceptTcpClient();
      //create a new socket helper to manage the connection
      SocketHelper sh=new SocketHelper(this,client);
      Console.WriteLine("Connected");
    }
  }
}

To run the server:

chatserver <port_number> <num_room>

E.g.: chatserver 1300 10 uses port 1300, and creates 10 chat rooms.

8.0 Client Program

The client program starts by connecting to the server. It then attempts to perform authentication. If successful, a thread is started to listen for the server's messages. A form is then loaded to show the UI and handle user's interaction.

public ChatClient(string _host,int _port)
{
    
    _currentpath=Path.GetDirectoryName(
      Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
            
    //store the host string
    host =_host;

    //store the port number
    port=_port;

    //Get the connection
    try
    {    
        tcpc=Connect(host,port);
        stream=tcpc.GetStream();
        Stream=stream;
    }
    catch//(Exception e)
    {
        //Console.WriteLine(e);
        Environment.Exit(0);    
    }


    //Initialize the GUI
    init_components();    
    
    //Start Listening
    tl=new Thread(new ThreadStart(Listen));
    tl.Start();
 
}

To run the client program:

chatclient <server_name> <port_no>

E.g.: chatserver localhost 1300.

9.0 Chat Client User Interface

The user can either key in commands at the textbox, or use the menu system. The code below shows the implementation of the menu system:

private void init_components()
{
    //shpE1=new ShapeControl.ShapeControl();

    //font
    cfont=new Font("Arial",14);
    
    //form
    //form=new Form();
    this.Text="Client ISS Chat";
    this.ClientSize = new System.Drawing.Size(400,570);
    //this.FormBorderStyle=FormBorderStyle.FixedSingle;
    this.WindowState=FormWindowState.Minimized;
    this.TopMost=true;

    //shp1 holds the reference to the media file that is loaded
    shp1=new ShapeControl.ShapeControl();
    this.Controls.Add(shp1);
    shp1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(124)), 
                     ((System.Byte)(92)), ((System.Byte)(159)), 
                     ((System.Byte)(83)));
    shp1.BorderColor = System.Drawing.Color.FromArgb(((System.Byte)(177)), 
                       ((System.Byte)(131)), ((System.Byte)(255)), 
                       ((System.Byte)(4)));
    shp1.BorderStyle = System.Drawing.Drawing2D.DashStyle.Solid;
    shp1.BorderWidth = 3;
    shp1.CenterColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), 
                       ((System.Byte)(0)), ((System.Byte)(0)));
    shp1.Font = new System.Drawing.Font("Arial", 8F, 
                System.Drawing.FontStyle.Bold);
    shp1.Location = new Point(5,495);
    shp1.Shape = ShapeControl.ShapeType.RoundedRectangle;
    shp1.Size = new System.Drawing.Size(150, 35);
    shp1.SurroundColor = System.Drawing.Color.FromArgb(((System.Byte)(0)), 
                         ((System.Byte)(0)), ((System.Byte)(255)));

    shp1.Text = "Empty";
    shp1.UseGradient = false;
    
    //context menu for shp1
    contextmenu_shp1=new ContextMenu();
    contextmenu_shp1.MenuItems.Add(new 
           MenuItem("Load Media File",new EventHandler(LoadMedia)));
    contextmenu_shp1.MenuItems.Add(new MenuItem("Play Media File", 
           new EventHandler(PlayMediaFile)));           
    
    shp1.ContextMenu=contextmenu_shp1; 
       
    //rtb
    rtb=new RichTextBox();
    //rtb.Controls.Add(shpE1);

    this.Controls.Add(rtb);
    rtb.DetectUrls=true;
    rtb.LinkClicked+=new LinkClickedEventHandler(rtb_LinkClicked);
    rtb.Top=0;
    rtb.Left=0;
    rtb.Width=400;
    rtb.Height=400;
    rtb.BackColor=Color.LightBlue;
    rtb.Font=new Font("Arial Unicode MS",10,FontStyle.Bold);
    rtb.ReadOnly=true;
    rtb.TabStop=false;
    
    //checkbox
    checkbox=new CheckBox();
    this.Controls.Add(checkbox);
    checkbox.Text="Auto Retrieve Picture/Media";
    checkbox.Size=new Size(200,15);
    checkbox.Checked=true;
    checkbox.Location=new Point(5,405);
    checkbox.TabStop=false;    

    //button
    button=new Button();
    this.Controls.Add(button);
    button.Text="Clear Messages";
    button.Size= new Size(120,20);
    button.Location=new Point(275,400);
    button.TabStop=false;

    //contextMenu for picture box
    contextmenu=new ContextMenu();
    MenuItem menuItem1 = 
        new MenuItem("Clear Picture Box", 
        new EventHandler(ClearPicture));
    MenuItem menuItem2 = 
        new MenuItem("Load Picture(s)", 
        new EventHandler(LoadPictureFile)); 

    contextmenu.MenuItems.Add(menuItem1);
    contextmenu.MenuItems.Add(menuItem2);   

    //pic
    pic=new PictureBox();
    this.Controls.Add(pic);
    pic.BackColor = Color.White;
    pic.Location = new Point(5, 425);
    pic.Size = new Size(390, 60);
    pic.BorderStyle=BorderStyle.FixedSingle;
    pic.Image=new Bitmap(390,60,PixelFormat.Format32bppArgb);
    pic.ContextMenu=contextmenu;
    pic.TabStop=false;

    //textbox
    textbox=new TextBox();
    this.Controls.Add(textbox);
    textbox.Location=new System.Drawing.Point(5, 540);
    textbox.Size=new Size(390,18);
    textbox.MaxLength=240;
    textbox.TabIndex=0;
    textbox.TabStop=true;
    textbox.Font=new Font("Arial Unicode MS",12);
    
    // Create an empty MainMenu.
    MainMenu mainMenu1 = new MainMenu();

    MenuItem mItem1 = new MenuItem("&Command");
    mItem1.Popup +=new EventHandler(CommandPopUp);

    p_smItem5=new MenuItem(":send pic:"); 
    p_smItem6=new MenuItem(":get pic:");
    p_smItem7=new MenuItem(":private:");

    p_smItemS1=new MenuItem(":send media:");
    p_smItemS2=new MenuItem(":get media:");
   

    mItem1.MenuItems.Add(new MenuItem(":help", 
                 new EventHandler(Commands)));
    mItem1.MenuItems.Add(new MenuItem(":list all", 
                 new EventHandler(Commands)));
    mItem1.MenuItems.Add(new MenuItem(":change room", 
                 new EventHandler(Commands)));
    mItem1.MenuItems.Add(new MenuItem(":which room", 
                 new EventHandler(Commands)));
   
   mItem1.MenuItems.Add(p_smItemS1);
   mItem1.MenuItems.Add(p_smItemS2);
   mItem1.MenuItems.Add(p_smItem5);
   mItem1.MenuItems.Add(p_smItem6);
   mItem1.MenuItems.Add(p_smItem7);
   
   mItem1.MenuItems.Add(new MenuItem(":quit", 
                 new EventHandler(Commands)));
   
   MenuItem mItem2 = new MenuItem("&Picture");
   mItem2.MenuItems.Add(new MenuItem("Clear Picture", 
                 new EventHandler(ClearPicture)));
   mItem2.MenuItems.Add(new MenuItem("Load Picture(s)", 
                 new EventHandler(LoadPictureFile)));

   MenuItem mItem3=new MenuItem("&Media");
   mItem3.MenuItems.Add(new MenuItem("Load Media File", 
                 new EventHandler(LoadMedia)));
   mItem3.MenuItems.Add(new MenuItem("Play Media File", 
                 new EventHandler(PlayMediaFile)));
  
   // Add two MenuItem objects to the MainMenu.
   mainMenu1.MenuItems.Add(mItem1);
   mainMenu1.MenuItems.Add(mItem2);
   mainMenu1.MenuItems.Add(mItem3);
   
   // Bind the MainMenu to Form1.
   this.Menu = mainMenu1;    

   //events
   this.SizeChanged +=new EventHandler(textbox_SizeChanged);
   textbox.KeyPress += new KeyPressEventHandler(textbox_KeyPressed);
   pic.MouseMove += new MouseEventHandler(this.pic_MouseMove);
   pic.MouseDown += new MouseEventHandler(this.pic_MouseDown);
   this.Activated +=new EventHandler(form_Activated);
   this.Closing +=new CancelEventHandler(form_Closing);
   rtb.TextChanged +=new EventHandler(rtb_TextChanged);
   button.Click +=new EventHandler(button_Click);
   memberColor=new Hashtable();

}

private void CommandPopUp(object sender,System.EventArgs e)
{
    pause_listening=true;
    Thread.Sleep(0);
    responseData="";
    Write(":list all");
    
    //if no data had been read after the write
    //attempt to read
    if(responseData==""){
      responseData=Read();
    }    
        
    string[] s=responseData.Split('\n');
    
    ArrayList arrlist=new ArrayList();
    foreach(string s1 in s)
     if(s1.Trim()!="")
     {
       string[] s2=s1.Trim().Split(':');
        
       if ((s2.Length==2)&& (s2[0].IndexOf("server>")<0))
              arrlist.Add(s2[0].Trim());
    }
      
    
    p_smItemS1.MenuItems.Clear();
    p_smItemS2.MenuItems.Clear();  
    p_smItem5.MenuItems.Clear();
    p_smItem6.MenuItems.Clear(); 
    p_smItem7.MenuItems.Clear(); 
    
    foreach(string name in arrlist)
    {
    
        p_smItemS2.MenuItems.Add(new MenuItem(name, 
                 new EventHandler(Param1Command)));
        if(!shp1.Text.Equals("Empty"))
           p_smItemS1.MenuItems.Add(new MenuItem(name, 
                      new EventHandler(Param1Command)));
        p_smItem5.MenuItems.Add(new MenuItem(name, 
                      new EventHandler(Param1Command)));
        p_smItem6.MenuItems.Add(new MenuItem(name, 
                      new EventHandler(Param1Command)));
        p_smItem7.MenuItems.Add(new MenuItem(name+":", 
                      new EventHandler(Param1Command)));              
    }
    
    responseData=""; 
    pause_listening=false;
    Thread.Sleep(0);
}

private void Param1Command(object sender,System.EventArgs e)
{
    string p=((MenuItem)((MenuItem)sender).Parent).Text.Trim();
    string s=((MenuItem)sender).Text.Trim();
    if (p.ToUpper()==":PRIVATE:")
    {
     textbox.Text=p+s+"<Key in Message>";
     textbox.SelectionStart=textbox.Text.Length-16;
     textbox.SelectionLength=16;
    }
    else
     Write(p+s);
}

10.0 Conclusion

I hope that the readers will benefit from this article and its associated code. I would welcome any comments and contributions.

Happy picture chatting.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralUnicode
Mizan Rahman
5:08 24 Jun '09  
Hi,

Since you have done lot unicode processing. I think this question is suitalbe for you.

I have a Windows Form in C# with a text box and a button.

Here is what I would like to do:

User will type text in the textbox and then press botton. The click event of the button will simply say save the text in a database. I would like the user to be able to type in UNICODE charecter as well.
For example, below is the content of the text box on the screen:
My Pi: \u03a0 and my Sigma \u03a3
In my button click event, how I can escap the string for unicode so that I get a PI and a sigma symbols?


Thank you.
Mizan
GeneralRe: Unicode
Yang Kok Wah
14:17 24 Jun '09  
Hi Mizan,

Try using the Character Map utility in Windows. You can assess it via Start>All Programs>Accessories>System Tools>Character Map.

Regards,
Yang Kok Wah
GeneralPictureChat - C# App
Owen oj
8:09 25 May '09  
This program is wonderful. I've never experienced how good this chat would be. But there is one problem. When you want to view the form, you get a simple error. I dont know why people release things when there not fully optional compatiable.

Now I'm not moaning, or being "mean" what some people suggest, but If I was going to release a "Game" or "Application" I would "CHECK" if there were any errors. As I am sick of going through app after app finding stupid errors what LACK of programming has been coded in. If someone could fix picturechat in C#, I would be honered to finally see something working for once in a life time.

Kind regards,

- Owen
GeneralRe: PictureChat - C# App
Yang Kok Wah
5:07 26 May '09  
I am glad that you like the chat program.
The code was originally designed to be hand coded without the use of Visual Studio and thus the object: ChatClient which extends from ChatStream cannot be loaded in the Visual Studio Designer.
However, all the other features like intellisense for code completion and lookup are still possible if you load only the code for these cs files.
You are welcome to amend the codes to make these 2 forms editable by Visual Studio. One suggestion is to create new forms and paste in all the codes and start from there..
Questioninternet
Member 937521
22:18 30 Jun '08  
does it works on internet or just on networks?
AnswerRe: internet
The_Mega_ZZTer
19:59 31 Jul '08  
The internet IS a network.
Generalsimple bug
abdelrady2030
5:45 25 Jun '08  
TcpClient client=new TcpClient(endpoint ip,int Port); this Constructor will bind client Socket to ip and given Port ... Not to connect to the given ip.

so client will work local and When Tested remotely has been failed

small refinement to code will make client application to work.
TcpClient client=new TcpClient();
client.Connect(hostNameOrIP,Port);
return client;
sorry for my bad english..........


no quote yet

Questionsend large picture and chat simultaneously
fabianse
22:41 21 Dec '07  
Does somebody has any advice about to transfer files and chat at the same time?
Like MSN Messenger does.
Thanks
AnswerRe: send large picture and chat simultaneously [modified]
fabianse
22:23 30 Dec '07  
Well... For those who read my previous question....
One solution I found is to make 2 connections with two networkStream to the server from the same client (same IPs, same PORTs).
In one stream we send and receive chat and general commands.
And... when the client wants to send a file, it connects again with the server creating a new Socket/NetworkStream, sends the command for signaling a file transfer, sends the length of the file, en sends the file with WriteBinary of this article.

The new stream for file transfer must be handled for a separated thread, so the user can continue chatting.

Have a nice day! =)

modified on Monday, December 31, 2007 4:09:27 AM

Generalhellow
bint_alnoooor
8:35 19 Dec '07  
how I can collect this codes
I understand every pice .. but I can not collect it
pleas help me
by
GeneralCan you give me the whole code ?
eric_wcx
1:22 7 Aug '07  
I cannot run the project.
I think that code is segmental.
Can you give me the whole code ?
Thank you !!

wenchenxi@163.com

Eric.Wen
Generalnice
86848325
3:23 7 Jun '07  
good job!Big Grin
Questionchatting using C#
vamshi reddy
3:28 7 Feb '07  
I am trying to develop a chat application using asp.net(C#).but i have no idea how to start and where to start.can any one help me out.........

Generaltread problem
remuz_cool
5:44 16 Nov '06  
when i try to run program, after i register, some message preview like this
"Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on."
( in client program ) and program will debug.
I use C# express edition 2005 and i was converted from c#7.sln to c#version 8.

Please help me...
God Bless You
Cool
AnswerRe: tread problem
Zeeshi570
22:00 29 Apr '09  
i am also facing the same exception but i found the solution it s no to big problem jusst write this line in main thread

control.checkforillegalcrossthreadcalls=false

Best Regards,
Zeeshan Arshad
QuestionHow about version for asp.net?
dunglesi
23:25 5 Nov '06  
Can I use your solution for my asp.net site?
Questionhow to capture live video broadcasted stream
Winita S
0:46 29 Sep '06  
My server application broadcasting video on port 7001..
In client application i want to save that video to disk
How to do it ...
I'm working in C#..
Server application uses wmesdk.

Winita S
GeneralGood work.
vik20
3:21 8 Sep '06  
But how can we stop the client if there is no response from server for some time (Lets say 10 mins)

vikram
www.vikramlakhotia.com
GeneralRe: Good work.
Yang Kok Wah
21:51 9 Sep '06  
I am not sure of the problem that you encounter. There would be no response from the server/cleint if there is some problem with the communication. Anyway, you can just close the client's form to stop the client. Or you can issue the command :quit


Regards

Yang Kok Wah
GeneralRe: Good work.
vik20
19:56 10 Sep '06  
Thanks for the advise. But what I did was used a timer control which would call the server againg after some time.

Vikram
http://www.vikramlakhotia.com/


GeneralLatest Download
Yang Kok Wah
1:41 8 Aug '06  
For some system, there is a little problem when Command menu is clicked. I have found the problem to be caused by some synchronization issue and the ammended src can be download from

http://www.cyberway.com.sg/~kwyang/PictureChar2_src.zip


Regards

Yang Kok Wah
QuestionThe Source
petehdd
0:39 11 Jun '06  
Great Program Big Grin

Can you give me the source for it?, Visual Studio does not open it so I can not edit the program. As I wish to change a few things and do not know how to start from scratch.

Thanks

Peter
AnswerRe: The Source
Yang Kok Wah
21:28 11 Jun '06  
Have just made a Visual Studio Solution for the Chat program. Download via

http://www.starhub.net.sg/~kwyang/Chat.zip

Regards

Yang Kok wah
Generalcan i implement chat room in Pocket pc?
Pentellcc
3:48 22 May '06  
I wish to implement a chat room that use between PDA (pocket pc) and desktop pc using C#. Is it any idea to implement this? XML web service can implement this? or any other suggestion for it?

The chat room that I plan to implement is one to one conversation only. Besides, if one of them already started the conversation, other people can't make conversation with him unless he had closed the conversation. Is it possible implement in xml web service? How could xml web service checking the status of the person to see them in conversation or not?

GeneralFlash
TheTinSoldier
7:27 17 May '06  
Is it possible to use a flash gui/client with the server?

Thanks,

Matt


Last Updated 31 Jul 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010