qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請?jiān)L問 http://qaseven.github.io/

          Java的Socket網(wǎng)絡(luò)編程以及多線程

           1.Socket是代表兩臺機(jī)器之間網(wǎng)絡(luò)連接的對象(java.net.Socket)。
            Socket的建立如下,參數(shù)分別是服務(wù)器端的IP地址和端口號: Socket socket  =  new Socket("167.5.75.1",5000);
            2.客戶端(Client)Socket的使用
            2.1 從Socket讀出數(shù)據(jù)步驟:
          // 1.創(chuàng)建Socket連接,告知Server的IP地址以及端口號
          Socket socket = new Socket("127.0.0.1", 4242);
          // 2.創(chuàng)建InputStreamReader,用于讀取socket輸入流
          InputStreamReader stream = new InputStreamReader(socket.getInputStream());
          // 3.使用BufferedReader鏈接輸入流
          BufferedReader br = new BufferedReader(stream);
          // 4.讀出數(shù)據(jù)
          String line = null;
          while ((line = br.readLine()) != null)
          {
          System.out.println("Today's advice is: " + line);
          }
          // 5. 關(guān)閉輸入流BufferedReader
          br.close();
            2.2 向Scoket寫入數(shù)據(jù)步驟:
          // 1.創(chuàng)建Socket連接,告知Server的IP地址以及端口號
          Socket socket = new Socket("127.0.0.1", 4242);
          // 2.創(chuàng)建PrintWriter對象,用以接收socket輸出流
          PrintWriter writer = new PrintWriter(socket.getOutputStream());
          // 3.使用PrintWriter對象寫出輸出數(shù)據(jù)
          String advice ="Today's advice";
          writer.println(advice);
          // 4. 關(guān)閉連接
          writer.close();
            3.  服務(wù)器端(Server)Socket的使用
          // 1.創(chuàng)建一個SercerSocket,使用4242端口監(jiān)聽客戶端請求
          ServerSocket serverSocket = new ServerSocket(4242);
          System.out.println("The server is started, listening on port 4242");
          while (true)
          {
          // 2.ServerSocket的accept()在等待用戶連接的時(shí)候閑置;在用戶連接上來的時(shí)候,返回一個Socket來與客戶端通信
          Socket socket = serverSocket.accept();
          // 3.創(chuàng)建PrintWriter對象,用以接收socket輸出流
          PrintWriter writer = new PrintWriter(socket.getOutputStream());
          // 4.使用PrintWriter對象寫出輸出數(shù)據(jù)
          String advice = "notifier's blog";
          writer.println(advice);
          // 5. 關(guān)閉連接
          writer.close();
          }

           4.   線程的狀態(tài)
            線程總共有5種狀態(tài):
            1. 新建 (Thread t = new Thread())
            2. 就緒 (t.start())
            3. 運(yùn)行
            4. 堵塞
            線程被block的原因很多,比如: 等待IO操作, sleep(), 等待被占用對象釋放
            5.死亡
            5.解決線程同步化問題的方法是: 對使用到共享對象的方法使用synchronized
            需要注意的是:
            雖說是方法進(jìn)行了synchronized,但鎖不是加在方法上的而是對象上的,也就是說,是synchronized方法獲取對象鎖。如果對象(類)有兩個或者多個synchronized方法,就表示兩個線程不能同時(shí)進(jìn)入同一個方法,也不能同時(shí)進(jìn)入不同的方法。 因?yàn)橥粫r(shí)間,只有一個方法在占有對象鎖。
            6.synchronized代碼塊
            有時(shí)候在一個方法中做了很多事情,但只有一部分邏輯是需要synchronized的,這時(shí)候我們可以使用synchronized代碼塊。如下,其中this表示當(dāng)前對象:
          public void function()
          {
          doSomething();
          //以下方法需要同步化
          synchronized (this)
          {
          doCriticalStuff();
          moreCriticalStuff();
          }
          doSomeOtherThing();
          }
            7. 以下是一個Socket簡單的例子:
            客戶端代碼及詳細(xì)注釋:
          /**
          * @author notifier
          * @create 2010-9-25 上午10:12:10
          * @version 1.0
          */
          public class DailyAdviceClient
          {
          public static void main(String[] args)
          {
          DailyAdviceClient client = new DailyAdviceClient();
          client.receiveMsg();
          }
          public void receiveMsg()
          {
          try
          {
          // 1.創(chuàng)建Socket連接,告知Server的IP地址以及端口號
          Socket socket = new Socket("127.0.0.1", 4242);
          // 2.創(chuàng)建InputStreamReader,用于讀取socket輸入流
          InputStreamReader stream = new InputStreamReader(socket
          .getInputStream());
          // 3.使用BufferedReader鏈接輸入流
          BufferedReader br = new BufferedReader(stream);
          // 4.讀出數(shù)據(jù)
          String line = null;
          while ((line = br.readLine()) != null)
          {
          System.out.println("Today's advice is: " + line);
          }
          // 5. 關(guān)閉輸入流BufferedReader
          br.close();
          } catch (UnknownHostException e)
          {
          e.printStackTrace();
          } catch (IOException e)
          {
          e.printStackTrace();
          }
          }
          }
           服務(wù)器端代碼及詳細(xì)注釋:
          /**
          * @author notifier
          * @create 2010-9-25 下午07:06:54
          * @version 1.0
          */
          public class SimpleChatServer
          {
          // 保存客戶端列表
          private ArrayList clientList = new ArrayList();;
          public static void main(String[] args)
          {
          new SimpleChatServer().startUp();
          }
          /**
          * 負(fù)責(zé)服務(wù)器端的啟動
          *
          */
          public void startUp()
          {
          try
          {
          // 創(chuàng)建服務(wù)器端ServerSocket連接,監(jiān)聽端口號5000
          ServerSocket serverSocket = new ServerSocket(5000);
          // 輪詢等待客戶端請求
          while(true)
          {
          // 等待客戶端請求,無請求則閑置;有請求到來時(shí),返回一個對該請求的socket連接
          Socket clientSocket = serverSocket.accept();
          // 將該客戶端加入到列表中
          PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
          clientList.add(writer);
          // 創(chuàng)建ClientHandler對象,通過socket連接通信
          Thread t = new Thread(new ClientHandler(clientSocket));
          t.start();
          System.out.println("有Client連進(jìn)來");
          }
          }catch(Exception e)
          {
          e.printStackTrace();
          }
          }
          /**
          * 客戶端處理類, 主要負(fù)責(zé):
          * 1.接收客戶端發(fā)來的消息
          * 2.將消息轉(zhuǎn)發(fā)其他客戶端
          * @author sdniu
          * @create 2010-9-26 上午10:00:18
          * @version 1.0
          */
          public class ClientHandler implements Runnable
          {
          private BufferedReader reader;
          private Socket socket;
          /**
          * ClientHandler的構(gòu)造函數(shù)
          * @param clientSocket
          */
          public ClientHandler(Socket clientSocket)
          {
          try
          {
          // 得到socket連接
          socket = clientSocket;
          // 得到客戶端發(fā)來的消息
          InputStreamReader isReader = new InputStreamReader(socket.getInputStream());
          reader = new BufferedReader(isReader);
          } catch (IOException e)
          {
          e.printStackTrace();
          }
          }
          public void run()
          {
          String message;
          try
          {
          while((message = reader.readLine()) != null)
          {
          System.out.println("客戶端消息: " + message);
          // 將客戶端發(fā)來的消息轉(zhuǎn)發(fā)所有客戶端
          notifyAllClients(message);
          }
          } catch (IOException e)
          {
          e.printStackTrace();
          }
          }
          }
          /**
          *
          * @param message
          */
          public void notifyAllClients(String message)
          {
          // 得到客戶端列表的迭代器,語法格式為 Iterator it = clientList.iterator();
          Iterator it = clientList.iterator();
          while(it.hasNext())
          {
          try
          {
          // 得到的Iterator別忘了強(qiáng)制轉(zhuǎn)換回PrintWriter
          PrintWriter writer = (PrintWriter) it.next();
          writer.println(message);
          writer.flush();
          } catch (Exception e)
          {
          e.printStackTrace();
          }
          }
          }
          }
            8. 多線程Socket編程的例子, 代碼比較長, 放在下載里了, 鏈接如下:
            http://files.cnblogs.com/notifier/SimpleChatroom.7z

          posted on 2013-09-27 10:38 順其自然EVO 閱讀(185) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          <2013年9月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 合川市| 富平县| 松溪县| 惠水县| 临泽县| 汪清县| 墨脱县| 彩票| 阳信县| 海南省| 新邵县| 阳江市| 罗江县| 兴宁市| 陆良县| 武胜县| 开封县| 霍州市| 隆尧县| 桐梓县| 河南省| 承德县| 泾川县| 肥西县| 花莲市| 洛阳市| 宝兴县| 大同市| 沈丘县| 汽车| 申扎县| 青海省| 沙洋县| 霍城县| 呼伦贝尔市| 治多县| 牙克石市| 三台县| 天全县| 同心县| 大方县|