使用Java進行網絡編程,通常會用到TCP,UDP協議。TCP是面向連接的,是可靠的傳輸層協議;UDP是無連接的,但是效率更高。下面是一個簡單的使用Socket寫的一個小例子用來實現TCP協議通信。
Server.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @description:服務器端
* @date:(2015-9-13 下午8:41:06)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
//監聽端口
int port=8090;
//服務器端監聽8090端口
ServerSocket serverSocket=new ServerSocket(port);
//服務器端監聽客戶端的連接請求,accept方法是阻塞式的
Socket socket=serverSocket.accept();
/**
* 服務端從Socket的InputStream中讀
* 取數據的操作也是阻塞式的,如果從輸入
* 流中沒有讀取到數據程序會一直在那
* 裏不動,直到客戶端往Socket的輸出流中寫入了數據,或關閉了Socket的輸出流。
* 客戶端的Socket也是同樣如此
* */
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
StringBuffer sb=new StringBuffer();
String temp=null;
int index;
while((temp=reader.readLine())!=null){
//不設置結束符,可能輸入流會
if ((index = temp.indexOf("eof")) != -1) {//遇到eof時就結束接收
sb.append(temp.substring(0, index));
break;
}
sb.append(temp);
}
System.out.println("receive from client:"+sb.toString());
//輸出信息到客戶端
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
//讀取控制檯輸入
BufferedReader bufReader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("server say:");
writer.write(bufReader.readLine());
writer.write("hello client");
/**
* BufferedReader的readLine方法是一次讀一行的,
* 這個方法是阻塞的,直到它讀到了一行數據爲止程序纔會繼續往下執行,
* 那麼readLine什麼時候纔會讀到一行呢?直到程序遇到了換行符或者是對應流的
* 結束符readLine方法纔會認爲讀到了一行,纔會結束其阻塞,讓程序繼續往下執行。
* 所以我們在使用BufferedReader的readLine讀取數據的時候一定要記得在對應的輸出流裏面一定要寫入換行符
* */
writer.write("eof\n");//設置結束符
writer.flush();
writer.close();
bufReader.close();
reader.close();
socket.close();
serverSocket.close();
}
}
Client.java
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* @description:客戶端
* @date:(2015-9-13 下午8:48:49)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class Client {
public static void main(String[] args) throws IOException {
//要連接的服務器IP地址
String host="127.0.0.1";
//要連接的服務器監聽端口
int port=8090;
//與服務器端簡歷連接
Socket client=new Socket(host,port);
//設置超時間爲20秒 ,
client.setSoTimeout(20*1000);
//往服務端寫數據
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
//讀取控制檯
BufferedReader bufReader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("client say:");
writer.write(bufReader.readLine());
writer.write("hello server");
writer.write("eof\n");//設置結束符
writer.flush();
//接收服務端響應,socket從輸入流中讀取數據是一個阻塞式操作,讀取不到數據會一直阻塞
BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream(),"UTF-8"));
StringBuffer sb=new StringBuffer();
String tmp=null;
int index;
while((tmp=reader.readLine())!=null){
if ((index = tmp.indexOf("eof")) != -1) {//遇到eof時就結束接收
sb.append(tmp.substring(0, index));
break;
}
sb.append(tmp);
}
System.out.println("receive from server:"+sb.toString());
reader.close();
writer.close();
//Test
bufReader.close();
//Test
client.close();
}
}
說明:
1、服務器的ServerSocket的accept方法是用來監聽端口,當監聽到客戶端的socket連接請求是就會創建一個Socket;accept方法是阻塞式的,如果一直沒有監聽到客戶端Socket連接請求,它會一直阻塞下去。
2、Socket的getInputStream()方法也是阻塞式的,客戶端的Socket向服務端寫入數據後,假如調用getInputStream()方法想要獲取服務器端的輸出,它會一直阻塞,知道服務器端寫入數據或者流關閉。
3、寫入”eof“,用來作爲結束符,防止流一直阻塞。另外,BufferedReader的readerLine方法也是阻塞式的,知道讀取到一行位置,所以寫入的時候記得寫入換行符。