Winsock with C#

Discussion in 'C#' started by pradeep, Mar 8, 2007.

  1. pradeep

    pradeep Team Leader

    Joined:
    Apr 4, 2005
    Messages:
    1,645
    Likes Received:
    87
    Trophy Points:
    0
    Occupation:
    Programmer
    Location:
    Kolkata, India
    Home Page:
    http://blog.pradeep.net.in

    Introduction



    We use Winsock to establish connection between client and server . This is the beginning of everything in the computer of today's !!! The net is the most power tools of the programmers and you must learning to use it. In this article we will see how to create a simple chat program. The chat program will be just a server and a client, that you can connect from the internet ( or LAN ) and simply exchange text messages.

    What is Winsock



    The Winsock we are going to use is an COM (References) that we can add in our C# program so we can use it's features. When using the internet ( like from a web browser ) a lot of things happen behind the scenes. Packets are constructed by the softwares that are then being send through routers and others are being received by your Operating System and analyzed by the application that send it. In order to do such complicated things a lot of in formation like headers, packet size ,hashes ,packet order and many more are required to create the packets. You WILL NOT have to deal with that stuff using the Winsock control from C#(or any other language) Continue reading to see just how easy it is to effectively use Winsock.

    What do you need



    For this tutorial you will only need a computer running Windows ,Microsoft Visual Studio 2005 , and the will to learn!

    What are servers and clients



    To connect any 2 programs, you need at least one server and one client.

    The server will be the program that opens the ports on the hosting machine and receive the connections while the client is called the program that connects to the remote host. For example, when you connect to Google with your firefox ( or internet explorer ), your browser plays the role of the client that connects to the hosts that are running at Google. Most common is for the servers to be able to receive more than one connections from different clients These is called multithreaded socket servers , but I am not going to show you how they are made in this tutorial, just to keep things simple. What i am going to show you is simply 2 applications connecting together, and sending/receiving text strings.

    Writing the Client



    First create your client form..

    [​IMG]

    Now we have the form but it has no code inside, it's only the components.

    Remember that you need to add Winsock COM component control to your program, to do this right click on the toolbar that is left to the form ( where buttons ,labels... are) Then click on the "Choose Items ... " item from the menu bar and find "Microsoft Winsock Control 6.0" , Check it and click ok.

    [​IMG]

    And now the CODE!!! of the forms components

    Code:
    Boolean isConnect= false; // we use this Boolean to know if we are connected
    private void Connect_Click(object sender,EventArgs e)
    {
    	try
    	{
    		w1.Close(); // close the winsock in case it was open
    
    		// now is time to connect ;-))
    		// ipText and portText is textbox
    		// in ipText the user is write the host ip
    		// in portText the user is write the host port
    		// (BUT client and host MUST use the same port )
    		// if the server accept the connection the w1_connect event is raised
    		w1.Connect(IPText.Text, PortText.Text);
    
    	}
    	// with try - catch we take all the exception that maybe come and write it to the screen
    	catch (System.Windows.Forms.AxHost.InvalidActiveXStateException g)
    	{ 
    		DataInput.Text += "\n" + g.ToString(); 
    	}
    }
    
    private void Send_Click(object sender, EventArgs e)
    {
    	try
    	{
    		if (isConnect)
    		{
    			//this will send the data that we wrote in SendText textbox
    			w1.SendData(SendText.Text);
    
    			//we add what we said to screen
    			DataInput.Text += "\nClent(You ;-) : " + SendText.Text;
    
    			//after we send the data we clear the textbox
    			SendText.Text = "";
    		}
    		else
    			MessageBox.Show("You are not connect to any host ");
    	}
    	// with try - catch we take all the exception that maybe come and write it to the screen
    	catch (AxMSWinsockLib.AxWinsock.InvalidActiveXStateException g)
    	{
    		DataInput.Text += "\n" + g.ToString(); 
    	}
    	catch (Exception ex) 
    	{ 
    		DataInput.Text +="\n" + ex.Message; 
    	}
    }
    
    This is the part that you must control the event that happen to the Wnsock . To do that you must say to the system what event you want to control and handle .

    We need 3 specific event to use : (Error,ConnectEvent,DataArrival)
    Code:
    this.w1.Error += new AxMSWinsockLib.DMSWinsockControlEvents_ErrorEventHandler(this.w1_Error);
    this.w1.ConnectEvent +=new System.EventHandler(this.w1_ConnectEvent);
    this.w1.DataArrival += new AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEventHandler(this.w1_DataArrival);
    
    This code is written in InitializeComponent() (The method that design the form ) you can find this method to <Form Name>.Designer.cs

    One trick : When you type"this.w1.ConnectEvent +=" you can press TAB and then Visual Studio complete the sentence "new System.EventHandler(this.w1_ConnectEvent);"

    And if you press TAB again the Studio insert automatically the method w1_ConnectEvent that handle the event .

    The Handle method CODE:
    Code:
    // in case of any errors ( like when the host don't accept your connection request)
    // this event raises and the e.number and e.description hold the errors info
    void w1_Error(object sender, AxMSWinsockLib.DMSWinsockControlEvents_ErrorEvent e)
    {
    	DataInput.Text += "\n- Error : " + e.description;
    	isConnect = false;
    }
    
    // when the server sends any data this event raises
    private void w1_DataArrival(object sender, AxMSWinsockLib.DMSWinsockControlEvents_DataArrivalEvent e)
    {
    	// data is the variable that store the incoming msgbox
    	String data ="";
    
    	// dat is variable type object
    	// the method getData of Winsock take only general type object
    	// and we input data in the variable to use it next time by ref
    	Object dat = (object)data;
    
    
    	// with this command the data are
    	// being stored in the dat variable so
    	// we can use them.
    	w1.GetData(ref dat);
    
    
    	// change back the object dat to string
    	data = (String)dat;
    
    
    	// write data to the screen
    	// (adding a host ip in front of the string to know where this came from :o)
    	DataInput.Text += "\nServer - " + w1.RemoteHostIP + " : " + data ;
    
    }
    
    
    private void w1_ConnectEvent(object sender, EventArgs e)
    {
    	//there we write what we what our program to do
    	//when the connection with the host is established
    	//w1.remotehostip is a function that will return as the hosts ip
    	DataInput.Text += "\n - Connect Event : " + w1.RemoteHostIP;
    
    
    	isConnect = true;
    }
    

    Writing the Server



    Basically the server is pretty much the same as the client. I will only mention the differences. The working server code is included in the example source code that you can download

    Here is the Server Form...

    [​IMG]

    The first difference is in the Connection. While the client set a remote ip and a remote port and tried to connect on them, the server only needs to set a local port and listen to it.

    Listening on the port means that the program is monitoring for any connection request made by the clients on that specific port. This is what you must do for the 'Start Listening' Button :
    Code:
    private void Start_Click(object sender, EventArgs e)
    {
    	if (portText.Text != "")
    	{
    		//to create a connection we need a server(host).
    		//server we call the program that keeps a port open
    		//so the someone ( client ) can connect
    		//do open the port we must write the following code
    
    
    		//with this we set the port we want to use for .the connection
    		w1.LocalPort = Int32.Parse(portText.Text);
    
    		//this command opens the port and waits (listens) for a connection
    		w1.Listen();
    	}
    }
    
    private void Disconnect_Click(object sender, EventArgs e)
    {
    	w1.Close();//this will close the connection with the client
    	w1.LocalPort = Int32.Parse(portText.Text);
    	w1.Listen();//open the port to wait for another connection
    	DataInput.Text += "\n - Disconnected";
    }
    
    Now the next difference from the client is in the connection handling.

    The client had the Connect event that was triggered when the connection was established

    With the server we need to accept the request from the client before the connection is completed

    To do that we use the ConnectionRequest that is triggered when a client tries to connect on our host. the connection will be completed only if we accept the request.

    this.w1.ConnectionRequest +=new AxMSWinsockLib.DMSWinsockControlEvents_ConnectionRequestEventHandler(this.w1_ConnectionRequest);

    Bellow is the code that handles the connection request
    Code:
     //this event is called when a client request a connection with the server
    private void w1_ConnectionRequest(object sender,......AxMSWinsockLib.DMSWinsockControlEvents_ConnectionRequestEvent e)
    {
    	if (isConnected==true )
    	{
    		w1.Close ();
    	}
    
    	//with this commands we accept the connection request to the server..
    	w1.Accept (e.requestID );
    	isConnected =true;
    	//now we are connected with the client
    	DataInput.Text +="\n - Client Connected :" + w1.RemoteHostIP ;
    }
    
     
    Last edited by a moderator: Jan 21, 2017
    dekisugi17 and Vafadar like this.
  2. jtehrhart

    jtehrhart New Member

    Joined:
    Dec 7, 2007
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    I cannot find the link to download the example program. Does it exist?
     
  3. cwl1945

    cwl1945 New Member

    Joined:
    Feb 19, 2008
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    As previously stated by a previous post, some download code would really be nice. There is one main problem with this article. The Client Form is labeled "Server". I think the author just cut and pasted the wrong image. The Client form should have a text box for inputting the server's IP address -- going through the included code there is a IP TextBox which gives credence to the wrong form was cut and pasted in this article. A downloadable "working" version would be of great benefit to someone trying to learn from this example.
     
  4. morg

    morg New Member

    Joined:
    Apr 18, 2008
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Hi, did you see xf.server component that helps to create high performance servers in .net? I don't think that activex or com can provide better performance because there is more overhead with extra wrapper layer. Also there are memory and marshaling issues.
     
  5. CyCloneNL

    CyCloneNL New Member

    Joined:
    May 8, 2008
    Messages:
    7
    Likes Received:
    1
    Trophy Points:
    0
    Well it isnt the only way, and i believe not the easiest way either.

    Incorrect, a computer starts with a Motherboard. When you replace Computer with programming, you are incorrect again. You dont start with one of the hardest things, you start off easy.

    That whole sentence just Doesn't not make any sense, at all. Did you write it in your own language, and let some sort of online translator translate it for you?

    That must be the best sentence in the whole story!
    What if two clients connect?
     
    Scripting likes this.
  6. lespero

    lespero New Member

    Joined:
    Sep 9, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    I have try this example to my application.
    I have a problem to w1.Accept(e.requestId)...when the program goes there the client disconnect...does anybody have the same problem???
     
  7. Hrqls

    Hrqls New Member

    Joined:
    Nov 6, 2009
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Occupation:
    Software Engineer
    Location:
    Alkmaar, The Netherlands
    thanks for the project, it works like a charm (after 1 fix)

    i just had to change 1 piece to make it work :
    in w1_ConnectionRequest you should not check if you are connected, but always close the connection before you accept the incoming connection.
     
  8. Mostapha

    Mostapha New Member

    Joined:
    May 28, 2010
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    Please Hrqls,

    I can't get make it work. could you send me your source code at mostapha#hotmail.com.

    Anticipated thanks.

    Mos.
     
  9. iamscottj

    iamscottj New Member

    Joined:
    Aug 18, 2010
    Messages:
    6
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    US
    I think I agree somewhat to CyCloneNL because the fact that if it is a chat program, why does it only interacts with only one computer as a client? It must support multiple computers too. Its if it can interact with multiple clients and the incoming message should contain an indication of who is sending the message else everything will be confusing. Very confusing.
     
  10. muthuis

    muthuis New Member

    Joined:
    Oct 16, 2010
    Messages:
    10
    Likes Received:
    0
    Trophy Points:
    0
    Home Page:
    http://www.codersource.net
    Agree with morg here. Have been using XF .net for a year now and now my simultaneous connection anytime goes around 300 and haven't seen a performance issue. Touch wood.
     
  11. madhup

    madhup New Member

    Joined:
    Jan 11, 2011
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    please send the source code
     
  12. madhup

    madhup New Member

    Joined:
    Jan 11, 2011
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    please send me the source code , if u got it ?
     
  13. fedapon

    fedapon New Member

    Joined:
    May 5, 2011
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    1
    Hello,

    Is there any way to capture the CloseEvent of this control in the server? In VB6 is very easy, but in C# I can´t do it. I want to know when the remote client close the connección, to close my conection and start listening again to another client.

    In VB6 is something like this:
    Private Sub winsock1_CloseEvent()
    winsock1.close
    winsock1.listen
    End sub

    Thank you vey much
    Fernando
     
  14. skorec1

    skorec1 New Member

    Joined:
    Jun 16, 2011
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    please send the source code
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice