java基於TCP的socket編程簡單實現[代碼實踐過]

1.什麼是socket

  所謂socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。

  以J2SDK-1.3爲例,Socket和ServerSocket類庫位於java.net包中。ServerSocket用於服務器 端,Socket是建立網絡連接時使用的。在連接成功時,應用程序兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網絡連接來 說,套接字是平等的,並沒有差別,不因爲在服務器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過 SocketImpl類及其子類完成的。

  重要的Socket API:

  java.net.Socket繼承於java.lang.Object,有八個構造器,其方法並不多,下面介紹使用最頻繁的三個方法,其它方法大家可以見JDK-1.3文檔。

  . Accept方法用於產生"阻塞",直到接受到一個連接,並且返回一個客戶端的Socket對象實例。"阻塞"是一個術語,它使程序運行暫時"停留"在這個地方,直到一個會話產生,然後程序繼續;通常"阻塞"是由循環產生的。

  . getInputStream方法獲得網絡連接輸入,同時返回一個IutputStream對象實例,。

  . getOutputStream方法連接的另一端將得到輸入,同時返回一個OutputStream對象實例。

  注意:其中getInputStream和getOutputStream方法均會產生一個IOException,它必須被捕獲,因爲它們返回的流對象,通常都會被另一個流對象使用。

  2.如何開發一個Server-Client模型的程序

  開發原理:

  服務器,使用ServerSocket監聽指定的端口,端口可以隨意指定(由於1024以下的端口通常屬於保留端口,在一些操作系統中不可以隨意使用,所以建議使用大於1024的端口),等待客戶連接請求,客戶連接後,會話產生;在完成會話後,關閉連接。

  客戶端,使用Socket對網絡上某一個服務器的某一個端口發出連接請求,一旦連接成功,打開會話;會話完成後,關閉Socket。客戶端不需要指定打開的端口,通常臨時的、動態的分配一個1024以上的端口。

多個客戶同時連接:
主程序監聽一端口,等待客戶接入;同時構造一個線程類,準備接管會話。當一個Socket會話產生後,將這個會話交給線程處理,然後主程序繼續監聽。運用Thread類或Runnable接口來實現是不錯的辦法。

現在實現服務器端編程:(基於TCP方式)
MyServer .java
---------------------------------------------------
package server;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
//這個簡單的socket服務器端主要是說句Hello XXX,採用多線程實現
public class MyServer extends Thread {

private Socket s;

public static void main(String[] args) {
     MyServer.server();//main入口,一運行機器,就開通server服務。
}

public MyServer(Socket s) {
     this.s = s;
}

public void run() {
     try {
      OutputStream os = s.getOutputStream();
      InputStream is=s.getInputStream();
      byte[] bu=new byte[20];
      int len=is.read(bu);//從客戶端讀取消息
      String userName=new String(bu,0,len);
      Date d=new Date();
      System.out.println(userName+" is coming here at "+d.toLocaleString());//寫在服務器端控制檯的日誌顯示
      String welcome="hello,"+userName+"!";
      //System.out.println(welcome);
      os.write(welcome.getBytes());//返回給客戶端的歡迎信息
      os.close();
      is.close();
      s.close();
     } catch (Exception e) {
      e.printStackTrace();
     }
}

public static void server() {
     try {
      ServerSocket ss = new ServerSocket(9527); //服務器的套接字,端口爲9527
      while (true) {
       Socket s = ss.accept();
       new MyServer(s).start(); //用戶一進來就運行一個線程
      }
     } catch (Exception e) {
      e.printStackTrace();
     }
}
}


客戶端編程:
MyClient .java
---------------------------------
package client;

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

public class MyClient {

public static void main(String[] args) {
     //這裏先強迫用戶輸入用戶名,調用client(str)方法。
     String str = "";
     try {
      while (str.length() < 1) {
       System.out.println("請輸入您的名字");
       str = new DataInputStream(new BufferedInputStream(System.in))
         .readLine();
      }
     } catch (Exception e) {
      e.printStackTrace();
     }
     MyClient.client(str);
}

public static void client(String userName) {
     try {
      Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 9527);//套接字的IP地址和端口號
      OutputStream os = s.getOutputStream();
      InputStream is = s.getInputStream();
      byte[] Name = userName.getBytes("ISO-8859-1"); //這個是爲了中文亂碼問題
      os.write(Name);//向服務器發送消息
      byte[] serverSay = new byte[100];
      int len = is.read(serverSay);//接受服務器消息
      System.out.println(new String(serverSay, 0, len));//客戶端控制檯顯示服務器返回的信息
      is.close();
      os.close();
      s.close();//記住一定要關閉這些輸入,輸出流和套接字
     } catch (Exception e) {
      e.printStackTrace();
     }

}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章