公告版位
需要找什麼嗎? 左邊分類或許可以幫助你...

目前日期文章:201301 (6)

瀏覽方式: 標題列表 簡短摘要

// 本範例不適合用於對稱行網路,要解決此問題請先讓 Client 連線至 Server ,讓 Client 知道自己的 (公開/內部 IP ) 與其他人的 (公開/內部 IP ) ,再檢查自己公開 IP 是否與其他人的公開 IP 重複,如果有重複代表自己處於對稱行網路中,將使用內部 IP 進行通訊即可。

 Java 伺服器程式碼:

 

 package javaapplication1;

import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;

public class JavaApplication1 {

    public static void main(String[] args) throws Exception {
        byte[] buffer = new byte[65507];
        DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
        DatagramSocket ds = new DatagramSocket(5555); // Set Server Port
        System.out.println("伺服器啟動於 : "
                + InetAddress.getLocalHost().getHostAddress() + ":" + ds.getLocalPort());
        String msg = "No Message...";
        HashMap map = new HashMap();
        while (true) {
            dp = new DatagramPacket(buffer, buffer.length);
            ds.receive(dp);
            msg = new String(dp.getData(), 0, dp.getLength());

            String ipPort = dp.getAddress().getHostAddress() + ":" + dp.getPort();
            // 只要一連線就會把 IP 放進 map 裡
            map.put(ipPort, "");
            System.out.println(ipPort + " 傳來的訊息 : " + msg);

            // 回傳他們自己的 外網IP
            dp = new DatagramPacket(ipPort.getBytes(), ipPort.length(), dp.getAddress(), dp.getPort());
            ds.send(dp);


            // 如果 2 個人上線了...
            if (map.size() == 2) {
                ArrayList a = new ArrayList();
                for (Object ip_Port : map.keySet()) {
                    a.add(ip_Port.toString());
                }
                for (Object ip_Port : map.keySet()) {
                    String temp = "";
                    for (int i = 0; i < a.size(); i++) {
                        // 如果現在這個IP不等於之前存放在 map 裡的IP
                        // 簡單來說就是只要獲取對方的IP,並不需要用到自己的IP
                        if (!a.get(i).equals(ip_Port)) {
                            temp += a.get(i);
                        }
                    }
                    // 為每個連線端發送對方的 IP:Port
                    dp = new DatagramPacket(temp.getBytes(), temp.length(), getIP(ip_Port), getPort(ip_Port));
                    ds.send(dp);
                }
            }
        }
    }

    static InetAddress getIP(Object ipPort) throws UnknownHostException {
        return InetAddress.getByName(ipPort.toString().split(":")[0]);
    }

    static int getPort(Object ipPort) {
        return Integer.valueOf(ipPort.toString().split(":")[1]);
    }
}

 

 C# 客戶端程式碼:

 

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


class MyClient
{
    public static UdpClient uc = null;
    public static IPEndPoint otherIP = null;

    static void Main(string[] args)
    {
        // 伺服器的 IP 與 Port
        IPEndPoint servrIP = new IPEndPoint(IPAddress.Parse("122.121.9.25"), 5555);
        // 自訂要監聽的 Port
        IPEndPoint myIP = new IPEndPoint(IPAddress.Any, 4444);
        uc = new UdpClient(myIP.Port);
        string receive;
        byte[] b;

        // 向伺服器傳資料:
        b = System.Text.Encoding.UTF8.GetBytes("Hello Server");
        uc.Send(b, b.Length, servrIP);

        // 從伺服器取得目前電腦的IP:
        string myPublicIP = System.Text.Encoding.UTF8.GetString(uc.Receive(ref servrIP));
        Console.WriteLine("目前電腦的IP:" + myPublicIP);
        Console.WriteLine("\n|-----------------------------------|\n");

        // 從伺服器取得對方IP:
        receive = System.Text.Encoding.UTF8.GetString(uc.Receive(ref servrIP));
        otherIP = new IPEndPoint(IPAddress.Parse(receive.Split(':')[0]), int.Parse(receive.Split(':')[1]));

        // 打洞:
        b = System.Text.Encoding.UTF8.GetBytes("Hi");
        uc.Send(b, b.Length, otherIP);

        // 為監聽{uc.Receive()}建立一條執行緒:
        // ( 1.接收/2.發送 兩種功能建議個別建立執行緒
        // 如果沒有建立執行緒程式可能會鎖死 )
        new Thread(new MyReceiveThreadClass().MyRun).Start();

        // 傳送真正的資料:
        int i = 0;
        while (true)
        {
            b = System.Text.Encoding.UTF8.GetBytes("這是 " + myPublicIP + " 資料 : " + i++);
            uc.Send(b, b.Length, otherIP);
            //Thread.Sleep(1000);
        }
    }
}

class MyReceiveThreadClass
{
    public void MyRun()
    {
        while (true)
        {
            string receive = System.Text.Encoding.UTF8.GetString(MyClient.uc.Receive(ref MyClient.otherIP));
            Console.WriteLine(receive);
        }
    }
}

 

  伺服器輸出結果:

 ccccccccccccccccc  

 

黃彥霖 發表在 痞客邦 PIXNET 留言(5) 人氣()

    傳統 HashMap 必須輸入Key才能取得Value,但是常常會遇到沒有 Key 但是卻想要得到 Value ,這時可以考慮使用 HashMap 中的 keySet() 方法,要注意的是這種輸出結果的順序並不是依造放入(put)的順序,所以無法跟 ArrayList 一樣有順序性的,他只是把 HashMap 裡的 put 資料全部取出而已,這部分必須要注意。可以參考以下程式碼並比對輸出結果:

 

 import java.util.HashMap;

public class NewClass {

    public static void main(String[] args) {
        HashMap map = new HashMap();

        map.put("A", "111");
        map.put("B", "222");
        map.put("C", "333");
        map.put("D", "444");
        map.put("E", "555");
        map.put("F", "666");
        map.put("G", "777");
        map.put("H", "888");
        map.put("I", "999");


        for (Object key : map.keySet()) {
            System.out.println(key + " : " + map.get(key));
        }
    }
}


輸出結果如下:

AA11

 

 

 

 


黃彥霖 發表在 痞客邦 PIXNET 留言(1) 人氣()

    這邊主要的重點是 UdpClient 這個類別,雖然從字面上這個類別叫做 UDP 的 Client (客戶端),但實際上我們也可以用它來建立伺服器,簡單來說 UdpClient 類別可以同時建立 伺服器端 (Server) 與 客戶端 (Client) 兩種功能

    如果今天要建立伺服器端 UdpClient 則要宣告成 UdpClient uc = new UdpClient(5555); ,這裡的 5555 代表伺服器的 Port (監聽埠)。

    如果今天要建立客戶端 UdpClient 擇要宣告成 UdpClient uc = new UdpClient(); ,也就是不需要指定 Port,因為只是發送消息,並不是要接收,所以電腦會依流水號的方式分配Port,將資料傳到指定IP:Port上 (此時指定IP:Port是使用 IPEndPoint 類別)。

以下範例程式碼:

 

伺服器端:

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

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("這是伺服器...\n");

        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5555);
        UdpClient uc = new UdpClient(ipep.Port);

        int i = 0;
        while (true)
        {
            Console.WriteLine(System.Text.Encoding.UTF8.GetString(uc.Receive(ref ipep)));
            byte[] b = System.Text.Encoding.UTF8.GetBytes("這是'伺服器'回傳的訊息 ~ " + i++);
            uc.Send(b, b.Length, ipep);
        }
    }
}

客戶端:

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

class MainClass
{
        public static void Main (string[] args)
        {
                Console.WriteLine ("這是客戶端...\n");
                IPEndPoint ipep = new IPEndPoint (IPAddress.Parse ("127.0.0.1"), 5555);
                UdpClient uc = new UdpClient ();
            
                for (int i = 0; i<10; i++) {
                        byte[] b = System.Text.Encoding.UTF8.GetBytes ("這是'客戶端'傳送的訊息 ~ " + i);            
                        uc.Send (b, b.Length, ipep);
                        Console.WriteLine (System.Text.Encoding.UTF8.GetString (uc.Receive (ref ipep)));
                }                       
        }
}


執行結果:

aaa

黃彥霖 發表在 痞客邦 PIXNET 留言(0) 人氣()

先至 [ 管理後台 ] → [ 側邊欄位設定 ] → [ 頁尾描述 ] 貼上以下程式碼 :

<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shCore.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushCSharp.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushCss.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushDiff.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushJScript.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushPlain.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushSql.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushVb.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushXml.js"></script>
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/3.0.83/scripts/shBrushJava.js"></script>
<script type="text/javascript">
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/3.0.83/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/3.0.83/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/3.0.83/styles/shThemeDefault.css" id="shTheme"/>

這樣就完成了。接著發布文章(程式碼)前,請先把你的程式碼先經以下網址轉碼,程式碼排版才不會亂掉。

 

HTML 部落格轉碼 

http://www.string-functions.com/htmlencode.aspx

接著把轉碼後的程式碼貼製 pre 標籤裡面,如下:

<pre class="brush: html">

</pre>

如果你寫的是HTML則請把 brush 換成 html 如:brush: html

如果你寫的是JavaScript則請把 brush 換成 js如:brush: js

如果你寫的是C#則請把 brush 換成 js如:brush: csharp

 

黃彥霖 發表在 痞客邦 PIXNET 留言(1) 人氣()

using UnityEngine;
using System.Collections;
using System.Threading;
 
public class Test : MonoBehaviour
{
        My m;
 
        void Start ()
        {
                m = new My ();
                Thread t = new Thread (m.RunMe);
                t.Start ();
        }
 
        void OnApplicationQuit ()
        {
                m.Stop ();
        }
}
 
class My
{
        int i = 0;
        bool isRun = true;
 
        public void RunMe ()
        {
                while (isRun) { 
                        MonoBehaviour.print ("Run : " + i++);
                        Thread.Sleep (1000);
                }
        }
 
        public void Stop ()
        {
                isRun = false;
        }
}

黃彥霖 發表在 痞客邦 PIXNET 留言(0) 人氣()

// 精簡版
 
public class JPA03 {
    public static void main(String[] args) {
        java.util.Scanner s = new java.util.Scanner(System.in);
        int a,b,i;
        while(true){
            System.out.println("Input:");  
            if((i = (a = s.nextInt()))==999) break;            
            b = s.nextInt();            

黃彥霖 發表在 痞客邦 PIXNET 留言(2) 人氣()