<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-159  評論-114  文章-7  trackbacks-0

    一臺主機有個IP地址(邏輯地址),MAC(物理地址)。用IP可以找到一臺主機。

    能交換數據的是進程,進程之間交換數據,不是計算機。

    一個程序.exe,靜態(tài)的概念,一個進程,在內存中,運行態(tài)的概念。

    某些進程會占用固定的端口,進程與端口對應。

    把一個端口和進程建立聯系的叫做綁定。

    FTP《=》端口21

    進程間通訊是兩個端口建立連接。

    由于機器通訊,要有相同的語言,為保證數據正常交互,預先約定好協議。

    網絡體系架構,解決異構性問題采用的是分層方法--把復雜網絡互聯問題劃分為若干較小的,單一的問題。

    分層-〉人解決復雜網絡問題的一般思路。

    OSI :

    對等層不允許直接通訊,嚴格單項依賴,上層依賴下層提供的服務,下層不依賴于上層工作。

    對等層是虛擬連接。

    網絡層----〉IP協議(尋址)(路由)

    傳輸層----〉TCP傳輸控制協議,UDP用戶數據報協議

    TCP有很大開銷,三次握手,保證數據可靠傳輸,

    UDP用于對實時性要求的應用。他是把大塊數據分成小的數據報,只發(fā)數據報,數據報自己負責尋址,所以不一定路徑一樣,順序可能亂。



    數據封裝的概念,下一層對上層數據按照自己的格式進行再次封裝,封裝就是在數據前面加上特定的協議頭部信息。數據打包

    Untitled-1.jpg


    上層向一層一次,就封裝一次,到另外一層就是反向的,解封一次。

    TCP/IP

    應用層
    傳輸層
    網絡層
    網絡接口

    端口是一種抽象的軟件結構,與協議相關。

    TCP:23和UDP:23不相關。


    IP+Port就是一個Socket,是一個對象的概念。就好像電話機,電話號碼和分機號

    Socket是傳輸層的。網絡編程要注意在哪一個層次編程。

    基于TCP,java.net.ServerSocket,服務器進程。構造函數一個端口號

    Socket s  = ServerSocket.accept(),阻塞方法,可以返回一個與聯入的客戶端Socket對應的Socket。

    客戶端:Socket s1 = new Socket("127.0.0.1",6666);

    s和s1不同。

    獲得數據,s.getInputStream(),s.getOutputStream()

    s.close(),關閉socket,會自動關閉流,至少這時流不再可用。

    import java.io.*;
    import java.net.*;

    public class Server{
        
    public static void main(String[] args) throws Exception
        
    {
            ServerSocket ss 
    = new ServerSocket(8000);
            Socket s 
    = ss.accept();        
            PrintWriter out 
    = new PrintWriter(s.getInputStream());        
            out.println(
    "Server started!");
            out.flush();
            
            s.close();
            ss.close();
        }

    }

     

    import java.io.*;
    import java.net.*;

    public class Client{
        
        
    public static void main(String[] args) throws Exception
        
    {
            Socket s 
    = new Socket("127.0.0.1",8000);
            BufferedReader in 
    = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String str 
    = in.readline();
            System.out.println(str);
            
            BufferedReader br 
    = new BufferedReader(new InputStreamReader(System.in));
            br.readline();
        }

    }

    以上是最簡單的Server和Client。

    以下是本人編的多人群聊的聊天室。

    import java.io.*;
    import java.net.*;
    import java.util.*;

    public class NewServer{
      
    private ServerSocket ss;
      
    private int port = 7777;//默認端口
      private static int online = 0;//當前服務在線人數
      
      
    private List threadList;//客戶端連入Server后,啟動過的線程的集合,以便管理,群發(fā)
      final static PrintWriter sysout;//服務器本地輸出,無用,直接System.out,沒問題。
      
      
    static{
        sysout 
    = new PrintWriter(System.out,true);
      }

      
      
    public NewServer(int port)
      
    {
        
    if(port!=0){//參數為0,采用默認端口
          this.port = port;
        }

        
    try{
          ss 
    = new ServerSocket(this.port);//綁定
          threadList = new ArrayList();
          sysout.println(
    "Start service on " + this.port);
          
    while(true)//死循環(huán),用于處理客戶端的連入,并啟動獨立線程,與客戶端交換信息
          {
            Transmit t 
    = new Transmit(ss.accept());//阻塞住,直到有客戶端連接
            threadList.add(t);//將即將啟動的線程,加入list
            t.start();
          }

        }
    catch(Exception e)
        
    {
            e.printStackTrace();
        }

      }

      
      
    /**
      *
      * 私有成員內部類(便于訪問外部類私有屬性),如果改為頂級類沒有問題,封裝了服務器與客戶端交換數據的獨立線程操作。
      
    */
      
      
    private class Transmit extends Thread{
        
    private BufferedReader input;//帶緩沖的字符流,作為輸入流,從中讀取發(fā)送到服務器的信息
        private PrintWriter output;//帶緩沖的字符流,作為輸出流,輸入字符
        private String serverinfo = System.getProperty("os.name")+" "+System.getProperty("os.arch")+" "+System.getProperty("os.version");
        
    private Socket client;//ss.accept()返回的socket
        private boolean quit = false;//判斷是否退出
        
        
    public Transmit(Socket sock){
          
    this.client = sock;
          
    try{
            
    this.input = new BufferedReader(new InputStreamReader(client.getInputStream(),"gb2312"));
            
    this.output = new PrintWriter(client.getOutputStream(),true);//auto flush
            output.println("Now,Server has " + (online) + " people online!");
            output.println(serverinfo);
          }
    catch(Exception ex){}
        }

        
        
    public void run(){
          
    try{
            
    while(!quit)
            
    {           
              String line 
    = input.readLine();
              
    if(line == null) quit = true;
              
    else{
                sysout.println(
    ""+new Date().toString()+"Receive word From : "+client.getInetAddress()+" ]: " + line);//本地輸出,可以重定向到文件
                if(line.trim().equalsIgnoreCase("EXIT"))
                
    {
                  output.println(
    "See you");
                  quit 
    = true;              
                }

                
    else
                    sendToOtherMsg(client.getInetAddress().toString(),line);
    //遍歷threadlist,群發(fā)信息
              }

            }

            online
    --;
          }

          
    catch(SocketException e)
          
    {
              
    if(e.getMessage().indexOf("Connection reset")!=-1)//客戶端退出
              {
                  sysout.println(client.getInetAddress() 
    + "offline");
                  online
    --;
              }

          }

          
    catch(Exception e)
          
    {
            e.printStackTrace();
          }

          
    finally
          
    {
              
    try{
                  client.close();
    //socket會關閉所打開的流,不要強行關閉流,會有問題。
              }
    catch(Exception e){}
          }

        }

        
        
    //發(fā)送信息給其他線程所通訊的客戶端
        private void sendToOtherMsg(String ip,String msg)
          
    {
            Iterator it 
    = threadList.iterator();
            
    while(it.hasNext())
            
    {
                Transmit t 
    = ((Transmit)it.next());
                
    if(!t.isAlive()) //如果線程已經進入死亡狀態(tài),也就是線程已經運行完畢,remove掉
                {
                        it.remove();
                        
    continue;
                }

              t.sendIt(
    "["+ip+"]: "+msg);
              
            }

          }

          
          
    private void sendIt(String msg)
        
    {
          output.println(msg);      
        }

          
      }

      
      
    public static void main(String[] args)
      
    {
          
    new NewServer(61248);
      }

    }

    客戶端:

    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    public class ChatRoomClient{
      
    private JTextArea jta;
      
    private JTextField jtf;
      
    private JFrame f;
      
    private Socket conn;
      
    private BufferedReader echo;
      
    private PrintWriter pw;
      
    private boolean done = false;
      
    public ChatRoomClient(String host,int port){
        creatGUI();
        
        
    try{
          conn 
    = new Socket();
          conn.connect(
    new InetSocketAddress(host,port),10000);//Socket連接
          
          
    //通過橋轉換,將socket得到的字節(jié)輸入流按照gb2312編碼方式轉換為字符輸入流,再封裝為帶緩沖的過濾流
          echo = new BufferedReader(new InputStreamReader(conn.getInputStream(),"gb2312"));
          
          
    //直接使用PrintWriter這個過濾流封裝字節(jié)輸出流為字符流,并帶有緩沖,比BufferedWriter方法更多。
          pw = new PrintWriter(conn.getOutputStream(),true);//auto flush
          jta.append("Connected to " + conn.getInetAddress() + ":" + conn.getPort() + "\n");
          
    while(!done){
            String info 
    = echo.readLine();
            jta.append(info
    +"\n");
          }

          jta.append(
    "client will be closed in 2s.\n");
          Thread.sleep(
    2000);
          System.exit(
    0);
        }

        
    catch(SocketException ex)
        
    {
          
    if(ex.getMessage().indexOf("Connection reset")!=-1)//服務器關閉
            jta.append("Server down!\n");
          
    if(ex.getMessage().indexOf("Connection refused: connect")!=-1)//服務器不通
            jta.append("connection refused!\nplease check network!\n");
        }

        
    catch(Exception ex)
        
    {
          ex.printStackTrace();
        }

        
    finally
        
    {
          
    try{
            conn.close();
    //只關閉socket
          }
    catch(Exception ex)
          
    {
          }
       
        }

      }

      
      
    private void creatGUI()
      
    {
        jta
    =new JTextArea();
        jta.setEditable(
    false);
        jtf
    =new JTextField();
        f
    =new JFrame("Chat Client");
        JScrollPane jp
    =new JScrollPane(jta);//構建帶滑動條的JTextField
        f.getContentPane().add(jp);
        f.getContentPane().add(jtf,
    "South");//JDK 1.5取消getContentPane,直接add沒問題
        f.setSize(600,400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //右上角的叉子,生效,關閉窗體
        f.setVisible(true);//設置可見,否則不可見
        
        jtf.addActionListener(
    new ActionListener(){//添加事件處理
          public void actionPerformed(ActionEvent e){
            String s
    =jtf.getText();
            
    if(s.trim().equalsIgnoreCase("EXIT"))
              done 
    = true;//讓主線程的while退出,進而結束Client
            pw.println(s);//利用輸出流,輸出到服務器信息。
            jtf.setText("");
          }

        }
    );
      }

      
      
    public static void main(String[] args){
        ChatRoomClient c
    =new ChatRoomClient("127.0.0.1",7777);
      }

    }


      

    UDP編程

    編寫一個時間服務器,客戶端就向服務器索取一個時間。

    import java.io.*;
    import java.net.*;
    import java.util.*;

    public class Server{
        
        
    static byte[] getTime()
            Date d
    = new Date(); 
            
    return d.toString().getBytes(); 
      }
     
       
        
    public static void main(String[] args) throws Exception
        
    {
            
                DatagramPacket inDataPacket 
    = null;
                 DatagramPacket outDataPacket 
    = null;
                
    byte[] msg= new byte[100];
                
    byte[] time;
                
                InetAddress clientAddress;
                
    int clientPort;
                
                
                
                DatagramSocket datagramSocket 
    = new DatagramSocket(13);
                System.out.println(
    "UDP server active on port 13"); 
                
                
    while(true
                
                inDataPacket 
    = new DatagramPacket(msg, msg.length);
                
                
    // Get the message. 
                datagramSocket.receive(inDataPacket); 
                
                String s
    =new String(inDataPacket.getData());
                System.out.println(s);
                
                
    //============================================================
                
                
    // Retrieve return address information, including InetAddress 
                
    // and port from the datagram packet just recieved. 
                clientAddress = inDataPacket.getAddress(); 
                clientPort 
    = inDataPacket.getPort(); 
                  
                
    // Get the current time. 
                time = getTime(); 
      
                
    //set up a datagram to be sent to the client using the 
                
    //current time, the client address and port 
                outDataPacket = new DatagramPacket(time, time.length, clientAddress, clientPort); 
      
                
    //finally send the packet 
                datagramSocket.send(outDataPacket); 
                
            }
     
                
        }

    }


    UDP的端口與TCP上的端口沒關系,端口和協議有關。

    import java.io.*;
    import java.net.*;

    public class Client{
        
        
    public static void main(String[] args) throws Exception
        
    {
            DatagramSocket ds 
    = new DatagramSocket();
            String s 
    = "Hello World";
            DatagramPacket outDataPacket 
    = new DatagramPacket(s.getBytes(),s.length(),InetAddress.getLocalHost(),13);
            ds.send(outDataPacket);
            
            
    byte[] msg = new byte[100];
            String receivedMsg;
            DatagramPacket inDataPacket 
    = new DatagramPacket(msg, msg.length);
            ds.receive(inDataPacket);
            
            receivedMsg 
    = new String(inDataPacket.getData(), 0, inDataPacket.getLength()); 
        System.out.println(receivedMsg);
        
        
    //close the socket
        ds.close(); 
            
        }

    }

    服務器需要客戶端先向服務器發(fā)送一個信息,服務器才能提供服務。再回復信息,因為UDP面向非連接的。

    Socket之間交換數據。

    交換DatagramPacket,內容在字節(jié)數據中,發(fā)送方在Pocket寫上地址和端口,send。
    接收方必須準備一個空信,以便接收內容。received,將字節(jié)數組裝滿。

    =========================================

    URL編程

    import java.io.*;
    import java.net.*;
    import java.util.*;

    public class URLConnectionTest {  
        
       
    public static void main(String[] args) {  
           
          
    try {  
              
             String urlName;
             
    if (args.length > 0) urlName = args[0];
             
    else  urlName = "http://www.tarena.com.cn";
             
             
    //step 1. Create a URL
             URL url = new URL(urlName);
             URLConnection con 
    = url.openConnection();
             
             
    //step 2. Connect to the server
             con.connect();

             
    // print header fields

             
    int n = 1;
             String key;
             
    while ((key = con.getHeaderFieldKey(n)) != null{  
                String value 
    = con.getHeaderField(n);
                System.out.println(key 
    + " = " + value);
                n
    ++;
             }


             
    // print convenience functions
             System.out.println();
             System.out.println(
    "getContentType: " + con.getContentType());
             System.out.println(
    "getContentLength: " + con.getContentLength());
             
             System.out.println(
    "getContentEncoding: " + con.getContentEncoding());
             System.out.println(
    "getDate: " + con.getDate());
             System.out.println(
    "getExpiration: " + con.getExpiration());
             System.out.println(
    "getLastModifed: " + con.getLastModified());
             System.out.println();

            
    //step 3 and 4. Get an InputStream and encapsulate it
             BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));

             
    // print first ten lines of contents
             String line;
             n 
    = 1;
             
             
    //step 5. Read info from the stream
             while ((line = in.readLine()) != null && n <= 100{  
                System.out.println(line);
                n
    ++;
             }

             
             
    if (line != null) System.out.println(". . .");
             
          }

          
    catch (IOException exception) {  
             exception.printStackTrace();
          }

       }

    }





    posted on 2005-12-29 14:19 北國狼人的BloG 閱讀(377) 評論(1)  編輯  收藏

    評論:
    # re: Java網絡編程 2006-07-02 10:56 | Sophia
    GG,謝謝哦,你的源程序救了我一命啊!!!!  回復  更多評論
      

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


    網站導航:
     
    主站蜘蛛池模板: 最近2019中文免费字幕| 永久免费av无码网站yy| 亚洲精品无码成人| 亚洲午夜成人精品无码色欲| 亚洲校园春色另类激情| 国产精品亚洲片夜色在线| 亚洲人AV在线无码影院观看| 亚洲熟女精品中文字幕| 亚洲欧美日韩中文字幕在线一区| 亚洲依依成人亚洲社区| 亚洲精品V天堂中文字幕| 毛片亚洲AV无码精品国产午夜| 国产精品亚洲专区无码唯爱网 | 全部免费毛片在线| 全黄性性激高免费视频| 久久久久亚洲爆乳少妇无| 亚洲精品无码av人在线观看| 亚洲AV人无码综合在线观看| 亚洲精品午夜在线观看| 亚洲成a人片在线不卡| 亚洲AV性色在线观看| 特级做a爰片毛片免费看| 视频免费在线观看| 免费国产污网站在线观看15| 野花高清在线观看免费3中文 | 午夜男人一级毛片免费| 四虎永久免费影院| 久久亚洲国产成人影院网站 | 亚洲熟女一区二区三区| 亚洲最新永久在线观看| 久久精品国产亚洲av麻豆蜜芽 | 苍井空亚洲精品AA片在线播放 | 国产午夜无码精品免费看| free哆啪啪免费永久| 午夜免费福利网站| 久久久青草青青国产亚洲免观 | 亚洲人成在线中文字幕| 国产综合激情在线亚洲第一页| 大妹子影视剧在线观看全集免费| 最近中文字幕免费mv在线视频| 免费黄色网址入口|