Hi All,

I am new in programming, and currently learning from some samples. From a page, I tried to implement a TCP client server with the following page in WPF (visual studio 2008)

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
public class serv
{
    public static void Main()
    {
        try
        {
            IPAddress ipAd = IPAddress.Parse("172.21.5.99"); //use local m/c IP address, and use the same in the client
            /* Initializes the Listener */
            TcpListener myList = new TcpListener(ipAd, 8001);
            /* Start Listeneting at the specified port */
            myList.Start();
            Console.WriteLine("The server is running at port 8001...");
            Console.WriteLine("The local End point is :" + myList.LocalEndpoint);
            Console.WriteLine("Waiting for a connection.....");
            Socket s = myList.AcceptSocket();
            Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
            byte[] b = new byte[100];
            int k = s.Receive(b);
            Console.WriteLine("Recieved...");
            for (int i = 0; i < k; i++)
                Console.Write(Convert.ToChar(b[i]));
            ASCIIEncoding asen = new ASCIIEncoding();
            s.Send(asen.GetBytes("The string was recieved by the server."));
            Console.WriteLine("\nSent Acknowledgement");
            /* clean up */
            s.Close();
            myList.Stop();
        }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }
}

However, when I tried to compile it, I got an error,


Error 1 Program 'C:\Users\niub\Documents\Visual Studio 2008\Projects\WpfApplication5\WpfApplication5\obj\Debug\WpfApplication5.exe' has more than one entry point defined: 'WpfApplication5.App.Main()'. Compile with /main to specify the type that contains the entry point. C:\Users\niub\Documents\Visual Studio 2008\Projects\WpfApplication5\WpfApplication5\obj\Debug\App.g.cs 59 28 WpfApplication5

I know this is because there is another main in a file (which is strangely auto-generated) . I tried to delete this App.g.cs auto generated class, and it removed the error (but yet, my source sample code didn't show anything .. strangely :( )
Below is what is inside the App.g.cs :

#pragma checksum "..\..\App.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "DC57595DE0B4DB627E16D0F860D8BC4C"
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.3053
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Media.TextFormatting;
using System.Windows.Navigation;
using System.Windows.Shapes;


namespace WpfApplication5 {
    
    
    /// <summary>
    /// App
    /// </summary>
    public partial class App : System.Windows.Application {
        
        /// <summary>
        /// InitializeComponent
        /// </summary>
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public void InitializeComponent() {
            
            #line 4 "..\..\App.xaml"
            this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);
            
            #line default
            #line hidden
        }
        
        /// <summary>
        /// Application Entry Point.
        /// </summary>
        [System.STAThreadAttribute()]
        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public static void Main() {
            WpfApplication5.App app = new WpfApplication5.App();
            app.InitializeComponent();
            app.Run();
        }
    }
}

Can any of you help me to solve this problem, and try to give me a about this strangely autogenerated file?

Thank you

i found a solution here, but again, it's still kinda vague. Which line should I edit .. Still hoping for assistance from experienced fellows. THank you

I tried again, in the properties, changed the startup object to "serv" , instead of "not set" or "wpfapplication5.App". And it managed to compile sucessfully, but there is no console window showing that the server is running.. I will try again with some trial and errors.

I hope you have a solution. What I am suggest you that you should use Console application project instead of WPF app. In case if it is really needed then put your code in a constructor or load event.

I hope you have a solution. What I am suggest you that you should use Console application project instead of WPF app. In case if it is really needed then put your code in a constructor or load event.

Hi..

Thank you for anwering. I did not manage to do it :(
So I somehow trying to 'twist' my application, by creating a button, and put the socket code under it. So it look like this

private void button1_Click(object sender, RoutedEventArgs e)
        {
           try 
{
IPAddress ipAd = IPAddress.Parse("172.21.5.99"); //use local m/c IP address, and use the same in the client
/* Initializes the Listener */
TcpListener myList=new TcpListener(ipAd,8001);
/* Start Listeneting at the specified port */ 
myList.Start();
Console.WriteLine("The server is running at port 8001..."); 
Console.WriteLine("The local End point is :" + myList.LocalEndpoint );
Console.WriteLine("Waiting for a connection.....");
Socket s=myList.AcceptSocket();
Console.WriteLine("Connection accepted from "+s.RemoteEndPoint);
byte[] b=new byte[100];
int k=s.Receive(b);
Console.WriteLine("Recieved...");
for (int i=0;i<k;i++)
Console.Write(Convert.ToChar(b[i]));
ASCIIEncoding asen=new ASCIIEncoding();
s.Send(asen.GetBytes("The string was recieved by the server."));
Console.WriteLine("\nSent Acknowledgement");
/* clean up */ 
s.Close();
myList.Stop();
}
catch (Exception da) 
{
Console.WriteLine("Error..... " + da.StackTrace);
} 
}
}

I actually need to make a wpf application, that is also capable of detecting registered user, that is why I need to make a server within the wpf application, hoping that when I execute the wpf, the server would also turned on automatically. Up to this now, I tried to trigger the server by pressing a button, but when I compile this, it shows no error, but neither does any console shown. Only a button that does not show anything when pressed. Please guide me on this matter..

Thank you

Ok, let's start from the beggining ...
The task is make a WPF application. What we usually expect from server - is performance. From client we usually expect usability, attractiveness, etc. (also performance, but less than from server). So it would be logical to make a server part of an application as Console application (as adatapost mentioned). And the client part would be a WPF application. So let's describe the basic behaviour for both parts:
Server:

  1. Start
  2. Waiting for the client to connect
  3. Process client
  4. Goto step 2 if we're going to proceed, and goto step 4 if we're done
  5. Stop the server

Client:

  1. Connect to the server
  2. Interact with server
  3. Close connection to not occupied server for too long

So now you should make 2 applications (the Console one and WPF one for the server and client respectively). I would suggest you to create them within one solution to ease the control of them.

Ok, now we have basic algorythm and 2 empty projects created. Now - closer to code .. I've changed a bit the client and server part .. Let's start from server:

static void Main(string[] args)
        {
            //The IP adress of computer, where server is running
            IPAddress ipAd = IPAddress.Parse("127.0.0.1");
            //Initialize listener on given IP and port
            TcpListener myList = new TcpListener(ipAd, 8001);
            //Start Listening at the specified port
            myList.Start();
            Console.WriteLine("The server is running at port 8001...");
            Console.WriteLine("The local End point is :" + myList.LocalEndpoint);

            //Endless listening for the clients to connect
            while (true)
            {
                try
                {                    
                    Console.WriteLine("Waiting for a connection.....");
                    
                    //Start waiting for client to connect and
                    //return a socket for communciation between server and client
                    Socket s = myList.AcceptSocket();
                    Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

                    //Reading information from client
                    byte[] b = new byte[100];
                    int k = s.Receive(b);
                    Console.WriteLine("Recieved...");
                    for (int i = 0; i < k; i++)
                        Console.Write(Convert.ToChar(b[i]));
                    ASCIIEncoding asen = new ASCIIEncoding();
                    
                    //sending information back to client
                    s.Send(asen.GetBytes("\"" + asen.GetString(b, 0, k) + "\" was recieved by the server."));
                    Console.WriteLine("\nSent Acknowledgement");
                    Console.WriteLine();

                    //This is also nessesary part
                    //but for this case, when we have
                    //endless listening in a single-threaded
                    //application. So I just commented it.
                    /*s.Close();
                    myList.Stop();*/
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error..... " + e.StackTrace);
                }
            }            
        }

This code placed in the Main method, so it would be started as soon as you'll run this application.

Now the client part .. it would be just a bit complicated .. Within the client part application you have file "Window1.xaml" (that's by default ... in my example I've renamed it to the "Client.xaml"). I've added some controls to it ...

<Window x:Class="Client.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Client" Height="300" Width="300">
    <Grid>
        <RichTextBox Margin="0,35,0,74" Name="rtbLog" VerticalScrollBarVisibility="Auto" VerticalContentAlignment="Bottom" VerticalAlignment="Stretch"/>
        <Label Height="28" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" Width="120">Log:</Label>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="9,0,0,11" Name="txtToSend" VerticalAlignment="Bottom" Width="120" />
        <Button Height="23" Margin="137,0,66,11" Name="btnSend" VerticalAlignment="Bottom" Click="btnSend_Click">Send</Button>
    </Grid>
</Window>

Then goes the main part. The code file for this form would be called "Window1.xaml.cs" (or "Client.xaml.cs" in my case ... or whatever you name it) .. Now we should implement algorythm, described earlier:

public partial class Window1 : Window
    {
        TcpClient tcpclnt = new TcpClient();
        public Window1()
        {
            InitializeComponent();
            //Connection to the client at sturtup
            connect();
        }

        private void connect()
        {
            try
            {
                //Initializing new client
                tcpclnt = new TcpClient();
                rtbLog.AppendText("Connecting.....\n");
                
                //Attempting to connect to the server located
                //at "127.0.0.1" and at port 8001
                tcpclnt.Connect("127.0.0.1", 8001);
                rtbLog.AppendText("Connected.....\n");
                rtbLog.AppendText("Enter the string to be transmitted : \n");
            }
            catch (Exception e)
            {
                rtbLog.AppendText("Error..... " + e.StackTrace + "\n");
            }
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            //Connecting if we're not connected
            if(!tcpclnt.Connected)
                connect();

            String str = txtToSend.Text;
            //Extracting the stream to interact
            //with server
            Stream stm = tcpclnt.GetStream();

            //sending information to the server
            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] ba = asen.GetBytes(str);
            rtbLog.AppendText("Transmitting.....\n");            
            stm.Write(ba, 0, ba.Length);
            stm.Flush();

            //reading server response
            byte[] bb = new byte[100];
            int k = stm.Read(bb, 0, 100);

            for (int i = 0; i < k; i++)
                rtbLog.AppendText(Char.ToString((char)bb[i]));
            rtbLog.AppendText("\n");
            rtbLog.ScrollToEnd();

            //closing stream and client after
            //interaction
            stm.Close();
            tcpclnt.Close();            
        }
    }

Now we have a server and a client to interact with it. The server application should be stated first. Then - start the client part, type anything into the small filed in the bottom of the form and click "Send" button .. and voila :)

P.S. Ask if anything remained unclear ..

Comments
Greate Explanation.

Hi!
yes, it is working fine after I worked on my code based on your suggestion. Thank you!

This question has already been answered. Start a new discussion instead.