2016年9月25日 星期日

[C#] 網路程式練習(四)

還是一樣,照著書上範例打,只是不知為何,雙向通沒多久,就當了.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ConsoleApplicationbox
{
    class ChatBox
    {
        int port = 20;
        static void Main(string[] args)
        {
            ChatBox ChatBox = new ChatBox();
            if (args.Length == 0) ChatBox.ServerMain();
            else
                ChatBox.ClientMain(args[0]);
        }

        public void ServerMain()
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            newsock.Bind(ipep);
            newsock.Listen(10);
            Socket client = newsock.Accept();
            new TcpListener(client);
            newsock.Close();
        }

        public void ClientMain(String ip)
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Connect(ipep);
            new TcpListener(server);
            server.Shutdown(SocketShutdown.Both);
            server.Close();
        }

    }



    public class TcpListener
    {
        Socket socket;
        Thread inThread, outTHread;

        NetworkStream stream;
        StreamReader reader;
        StreamWriter writer;


        public TcpListener(Socket s)
        {
            socket = s;
            stream= new NetworkStream(s);
            reader = new StreamReader(stream);
            writer = new StreamWriter(stream);
            inThread = new Thread(new ThreadStart(inLoop));
            inThread.Start();
            outTHread = new Thread(new ThreadStart(outLoop));

            outTHread.Start();
            inThread.Join();  //等待inThread 執行序完成,才離開此函數
                                          //按照 inLoop的邏輯,這個函數永遠都不會跳出(inLoop 是無窮迴圈)
        }

        public void inLoop()
        {
            while(true)
            {
                String line = reader.ReadLine();
                Console.WriteLine("rec: " + line);
            }
        }


        public void outLoop()
        {
            String line = Console.ReadLine();
            writer.WriteLine(line);
            writer.Flush();
        }

    }

}





找到一本不錯的書:



2016年9月23日 星期五

[C#] 網路程式練習(三)

照書 Key.......

使用 TCP/IP 方式:

Client 端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication_TCPclient
{
    class Program
    {
        static void Main(string[] args)
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.100.1"), 20);

            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            server.Connect(ipep);

            int j = 0;
            while(true)
            {
                j++;
                string input = "Hello word !! \r\n";
                byte[] data = Encoding.UTF8.GetBytes(input);
                server.Send(data);
                for (int h = 0; h < 100000; h++) ;

                if (j > 10) break;
            }

            server.Shutdown(SocketShutdown.Both);
            server.Close();



        }
    }
}



Server端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace ConsoleApplicationTcpServer
{
    class Program
    {
        static void Main(string[] args)
        {

            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 20);
           
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            newsock.Bind(ipep);

            newsock.Listen(10);

            while(true)
            {
                Socket client = newsock.Accept();

                IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;

                Console.WriteLine("Client End Point= " + clientep);

                TcpListener listener = new TcpListener(client);

                Thread thread = new Thread(new ThreadStart(listener.run));

                thread.Start();


            }




        }
    }


public class TcpListener
    {
        Socket socket;

        public TcpListener(Socket s)
        {
            socket = s;
        }
        public void run()
        {
            try
            {
                while(true)
                {
                    byte[] data = new byte[1024];
                    int recv = socket.Receive(data);

                    if (recv == 0) break;
                    Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));
                }

                socket.Close();
            } catch(Exception e)
            {
                Console.WriteLine("Client " + socket.RemoteEndPoint + " Error:close");
                Console.WriteLine(e);
            }

        }
    }

}

成功 ^^



另一個程式;

Server 端:

using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;  //匯入集合物體功能

namespace WindowsFormsApplication_TCP
{
    public partial class Form1 : Form
    {
        TcpListener server;         //電話總機
        Socket Client;              //電話分機
        Thread Th_svr;              //電話總機開放中
        Thread Th_Clt;              //電話分機連線中
        Hashtable HT = new Hashtable();     //客戶名稱與通訊物件的集合(雜湊表)(Key:Name:Socket)

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //忽略跨執行緒處理的錯誤(允許跨執行緒存許變數)
            CheckForIllegalCrossThreadCalls = false;
            Th_svr = new Thread(ServerSub);
            Th_svr.IsBackground = true;
            Th_svr.Start();
            button1.Enabled = false;
        }

        private void ServerSub()
        {
            //Server IP and Port
            IPEndPoint EP = new IPEndPoint(IPAddress.Parse(textBox1.Text), int.Parse(textBox2.Text));
            server = new TcpListener(EP);   //建立伺服端監聽器(總機)
            server.Start(100);              //啟動監聽設定,允許最多連線數100人
            while(true)
            {
                Client = server.AcceptSocket();  //建立此客戶的連線物件Client
                Th_Clt = new Thread(Listen);     //建立監聽這個客戶連線的獨立執行緒
                Th_Clt.IsBackground = true;
                Th_Clt.Start();
            }
        }

        private void Listen()
        {
            Socket sck = Client;

            Thread Th = Th_Clt;

            while(true)
            {
                try
                {
                    byte[] B = new byte[1023];
                    int inLen = sck.Receive(B);
                    String Msg = Encoding.Default.GetString(B, 0, inLen);
                    String Cmd = Msg.Substring(0, 1);
                    String Str = Msg.Substring(1);
                    switch(Cmd)
                    {
                        case "0":
                            HT.Add(Str, sck);
                            listBox1.Items.Add(Str);
                            break;
                        case "9":
                            HT.Remove(Str);
                            listBox1.Items.Remove(Str);
                            Th.Abort();
                            break;
                    }
                }
                catch(Exception)
                {

                }
            }

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.ExitThread();
        }
    }
}

執行結果

















Client 端:

using System.Net;
using System.Net.Sockets;


namespace WindowsFormsApplicationTCP_Client
{
    public partial class Form1 : Form
    {

        Socket T;
        String User;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string IP = textBox1.Text;
            int Port = int.Parse(textBox2.Text);
            IPEndPoint EP = new IPEndPoint(IPAddress.Parse(IP), Port);

            T = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            User = textBox3.Text;

            try
            {
                T.Connect(EP);
                Send("0" + User);
            }
            catch(Exception)
            {
                MessageBox.Show("無法連上伺服器");
                return;
            }

            button1.Enabled = false;
        }

        private void Send(String str)
        {
            byte[] B = Encoding.Default.GetBytes(str);

            T.Send(B, 0, B.Length, SocketFlags.None); //使用連線物件傳送資烙
        }

    }
}

執行結果:








沒有連線過,不知是否有問題....




2016年9月22日 星期四

[C#] 網路程式練習(二)

UDP clint 及 server 的程式,照著 Key 吧......

Client 端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication_client
{
    class Program
    {
        static void Main(string[] args)
        {
            String str1 = "AAAAAA\r\n";

            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.100.1"), 5555);
            Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Dgram, ProtocolType.Udp);
            while(true)
            {
                server.SendTo(Encoding.UTF8.GetBytes(str1), ipep);
                for (int j = 0; j < 10000; j++) ;
            }

        }
    }

}

Server 端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;

namespace ConsoleApplicationserver
{
    class Program
    {
        static void Main(string[] args)
        {

            //開啟伺服器的 5555 連接埠,用來接收傳送到本機的訊息
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any,5555);

            //建立接收的 socket,並使用Udp 的 Datagram 方式接收
            Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            //綁定 Socket (network) 與 IPEndPoint(ipep),讓Socket 接收 5555 埠訊息
            newsock.Bind(ipep);

            Console.WriteLine("Waiting for a client");

            //建立Remote 物件以便取得封包的接收來源的 EndPoint 物件
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint Remote = (EndPoint)(sender);

            while(true)
            {
                byte[] data=new byte[512];
                int recv = newsock.ReceiveFrom(data, ref Remote);//接收對方傳來的封包
                Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv));


            }
        }
    }
}


成功 !!





另一本書找到的範例:


using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace WindowsFormsApplication_UDP
{

    public partial class Form1 : Form
    {

        UdpClient U;
        Thread Th;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            Th = new Thread(Listen);
            Th.Start();
            button1.Enabled = false;
        }


        //找出本機 IP
        private string MyIP()
        {
            string hn = Dns.GetHostName();  //取得本機電腦名稱
            IPAddress[] ip = Dns.GetHostEntry(hn).AddressList;//取得本機IP陣列(Maybe 多個)
            foreach (IPAddress it in ip)
            {
                if (it.AddressFamily == AddressFamily.InterNetwork)
                {
                    return it.ToString();   //回傳此IP字串
                }
               
            }
            return " ";//找不到合格IP,回傳空字串
        }




        private void Listen()
        {
            int Port = int.Parse(textBox1.Text);
            U = new UdpClient(Port);

            IPEndPoint EP = new IPEndPoint(IPAddress.Parse("127.0.0.1"),Port);
            while (true)
            {
                byte[] B = U.Receive(ref EP);
                textBox2.Text = Encoding.Default.GetString(B);
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                Th.Abort();
                U.Close();
            }
            catch
            {

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string IP = textBox3.Text;
            int Port = int.Parse(textBox4.Text);
            byte[] B = Encoding.Default.GetBytes(textBox5.Text);
            UdpClient S = new UdpClient();
            S.Send(B, B.Length, IP, Port);
            S.Close();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Text += "  " + MyIP();
        }
    }
}

執行畫面:


















跑的蠻順的....@@



2016年9月21日 星期三

[C#] 網路程式練習(一)

剖析網址 URL的範例,繼續 Key 加深印象......

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;

namespace ConsoleApplication_Internet_2
{
    class Program
    {
        static void Main(string[] args)
        {

            //Dos的命令列會以&符號做命令分隔字元,因此若要以指令模式下,網址中的&之後會被視為是下一個指令
            System.Uri URL=new System.Uri("http://findbook.tw/search?keyword_type=keyword&t=xxx");

            //System.Uri 類別之屬性
            Console.WriteLine("Absolute Path: " + URL.AbsolutePath);
            Console.WriteLine("Absolute Uri : " + URL.AbsoluteUri);
            Console.WriteLine("Host         : " + URL.Host);
            Console.WriteLine("Port         : " + URL.Port);
            Console.WriteLine("LocalPath    : " + URL.LocalPath);
            Console.WriteLine("IsDefaultPort: " + URL.IsDefaultPort);
            Console.WriteLine("IsFile       : " + URL.IsFile);
            Console.WriteLine("PathAndQuery : " + URL.PathAndQuery);
            Console.WriteLine("Query        : " + URL.Query);
            Console.WriteLine("Scheme       : " + URL.Scheme);
            Console.WriteLine("UserEscaped  : " + URL.UserEscaped);
            Console.WriteLine("UserInfo     : " + URL.UserInfo);

            Console.Read();
        }
    }
}

2016年9月20日 星期二

[C#] 網路程式練習



C# TCP 客戶端 2 種 (最小精簡) 寫法:
https://lolikitty.pixnet.net/blog/post/112329777


Get Local IP Address in C#
https://www.delftstack.com/howto/csharp/get-local-ip-address-in-csharp/


書本上操寫的範例:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;

namespace ConsoleApplication_Internet_1
{
    class Program
    {
        static void Main(string[] args)
        {
            //create IP address
            IPAddress ipAddr = IPAddress.Parse("210.59.154.30");
            Console.WriteLine("ipAddr=" + ipAddr);

            //create IP endpoint
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 80);
            Console.WriteLine("ipEndPoint" + ipEndPoint);

            // IP Endpoint 序列化為 SocketAddress
            SocketAddress socketAddr = ipEndPoint.Serialize();
            Console.WriteLine("socketAddr=" + socketAddr);

            Console.ReadKey();
        }
    }

}

執行結果:


繼續 key.....


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Net;
using System.Net.Sockets;

namespace ConsoleApplication_Internet_1
{
    class Program
    {
        static void Main(string[] args)
        {
            //create IP address
            IPAddress ipAddr = IPAddress.Parse("210.59.154.30");
            Console.WriteLine("ipAddr=" + ipAddr);

            //create IP endpoint
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 80);
            Console.WriteLine("ipEndPoint" + ipEndPoint);

            // IP Endpoint 序列化為 SocketAddress
            SocketAddress socketAddr = ipEndPoint.Serialize();
            Console.WriteLine("socketAddr =  " + socketAddr);

            //透過 DNS 找尋IP位址相對應之主機名稱
            IPHostEntry remoteHostEntry = Dns.GetHostEntry(ipAddr);
            Console.WriteLine("host of ip:" + ipAddr + "is" + remoteHostEntry.HostName);


            //由於主機有可能有一個以上的 Alias
            //因此程式中以迴圈方式判斷 Alias
            string[] aliasList = remoteHostEntry.Aliases;
            for(int i=0;i<=aliasList.Length-1;i++)
            {
                Console.WriteLine("Alias " + i + " : " + aliasList[i]);
            }


            //由於主機有可能有一個以上的IP address
            //因此主程式中以迴圈方式判斷 AddressList
            IPAddress[] addrList = remoteHostEntry.AddressList;
            for(int i=0;i<addrList.Length-1;i++)
            {
                Console.WriteLine("Address " + i + " : " + addrList[i]);
            }


            Console.ReadKey();
        }
    }

}





2016年9月14日 星期三

[Raspberry] 在Raspberry Pi 2 使用SPI(一)

Enable SPI Kernel Module

ls /dev 會看到有 spidev0.0 spidev0.1



程式::

#include <cstdlib>

#include <stdio.h>

#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <unistd.h>

#include <string.h>

using namespace std;

int spi_cs0_fd;

unsigned char spi_mode;
unsigned char spi_bitsPerWord;
unsigned int spi_speed;


int spiOpenPort()
{
    int *spi_cs_fd;
   
    int status_value=-1;
   
    spi_mode=SPI_MODE_0;
    spi_bitsPerWord=8;
    spi_speed=1000000;
   
    spi_cs_fd=&spi_cs0_fd;
   
    *spi_cs_fd=open("/dev/spidev0.0",O_RDWR);
   
    if(*spi_cs_fd<0)
    {
        printf("Open /dev/spidev0.0 failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_MODE,&spi_mode);
    if(status_value<0)
    {
        printf("W spi_mode failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_MODE,&spi_mode);
    if(status_value<0)
    {
        printf("RD spi_mode failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_BITS_PER_WORD,&spi_bitsPerWord);
    if(status_value<0)
    {
        printf("WR sp_bitsPerWord failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_BITS_PER_WORD,&spi_bitsPerWord);
    if(status_value<0)
    {
        printf("RD sp_bitsPerWord failed\r\n");
        exit(1);
    }
   
    status_value=ioctl(*spi_cs_fd,SPI_IOC_WR_MAX_SPEED_HZ,&spi_speed);
    if(status_value<0)
    {
        printf("WR spi_spped failed\r\n");
        exit(1);
    }
       
    status_value=ioctl(*spi_cs_fd,SPI_IOC_RD_MAX_SPEED_HZ,&spi_speed);
    if(status_value<0)
    {
        printf("RD spi_spped failed\r\n");
        exit(1);
    }
         
    return(status_value);   
}


int SpiWriteAndRead(unsigned char *data,int length)
{
    struct spi_ioc_transfer spi[length];
    int i=0;
    int retVal =-1;
    int *spi_cs_fd;
   
    spi_cs_fd=&spi_cs0_fd;
   
    for(i=0;i<length;i++)
    {
        memset(&spi[i],0,sizeof(spi[i]));
        spi[i].tx_buf=(unsigned long)(data+i);
        spi[i].rx_buf=(unsigned long)(data+i);
        spi[i].len=sizeof(*(data+i));
        spi[i].delay_usecs=0;
        spi[i].speed_hz=spi_speed;
        spi[i].bits_per_word=spi_bitsPerWord;
        spi[i].cs_change=0;
    }
   
    retVal=ioctl(*spi_cs_fd,SPI_IOC_MESSAGE(length),&spi);
   
    if(retVal<0)
    {
        printf("tran error \n\r");
        exit(1);
    }
    return retVal;  
}


int main(int argc, char** argv) {

    unsigned char buffer[100];
   
    for(int j=0;j<100;j++)buffer[j]=0x55;
   
    if(spiOpenPort()<0)
    {
        return -1;
    }

    SpiWriteAndRead(buffer,100);
   
    close(spi_cs0_fd);
   
    return 0;
}





 參考資料:

Using the SPI Interface
C library for Broadcom BCM 2835 as used in Raspberry Pi
Interfacing an SPI ADC(MCP3008) chip to Raspberry Pi using C++(spidev)




















2016年9月13日 星期二

[Raspberry] 在Raspberry Pi 2 使用SPI

C library for Broadcom BCM 2835 as used in Raspberry Pi 提及:
in order for bcm2835 library SPI to work, you may need to disable the SPI kernel module using:
sudo raspi-config
under Advanced Options - enable Device Tree
under Advanced Options - disable SPI
Reboot.
所以我就跟著做了…..


程式:
#include <cstdlib>

#include <bcm2835.h>
#include <unistd.h>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv) {

    bcm2835_init();
   
    //setup spi pins
    if(bcm2835_spi_begin()==0)
    {
        printf("init failed \r\n");
        return -1;
    }
   
    //set CS pins polarity to low
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0,0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1,0);
  
    //set clock speed
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32768);
   
    //set SPI data mode
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
   
   
    //Set with CS pin to use for next transfers
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
   
    //transfer  byte
    char buf[100];
    for(int j=0;j<100;j++)
    {
        buf[j]=0x55;
    }
    for(int j=0;j<10;j++)
    {
     bcm2835_spi_transfern(&buf[0],100);
    
     bcm2835_delay(1000);

    }
  
    //return spi pins to default input state
    bcm2835_spi_end();
    return 0;
}
從示波器上,發現只有j=0才會有CLK,其他時間CLK都不見(是否是因為沒接裝置沒有正常回應…)...不知勒