天天看點

loading黑馬程式員之網絡程式設計:聊天(3-1)

-------android教育訓練 、java教育訓練、期待與您交流! ----------

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

Socket是網絡上運作的兩個程式間雙向通訊的一端,它既可以接受請求,也可以發送請求,利用它可以較為友善的編寫網絡上的資料的傳遞。在java中,有專門的socket類來處理使用者的請求和響應。利用SOCKET類的方法,就可以實作兩台計算機之間的通訊。這裡就介紹一下在JAVA中如何利用socket進行網絡程式設計。

在Java中Socket可以了解為用戶端或者伺服器端的一個特殊的對象,這個對象有兩個關鍵的方法,一個是getInputStream方法,另一個是getOutputStream方法。getInputStream方法可以得到一個輸入流,用戶端的Socket對象上的getInputStream方法得到的輸入流其實就是從伺服器端發回的資料流。GetOutputStream方法得到一個輸出流,用戶端Socket對象上的getOutputStream方法傳回的輸出流就是将要發送到伺服器端的資料流,(其實是一個緩沖區,暫時存儲将要發送過去的資料)。

UDP實作:

package com.heima.net;


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


/**
 * 用udp編寫一個聊天程式
 * 多線程:發送和接受資料
 */
public class ChatDemo {


public static void main(String[] args) {
try {
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10004, InetAddress.getByName("192.168.1.103"));
new Thread(new Send(sendSocket)).start();
new Thread(new Rece(receSocket)).start();
} catch (Exception e) {
e.printStackTrace();
}
}


}


//發送線程
class Send implements Runnable{
private DatagramSocket ds;
public Send(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
//255是群發,192.168.1.1~192.168.1.254之間的所有ip都可以接受
InetAddress.getByName("192.168.1.255"), 10002);
ds.send(dp);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}


//接受線程
class Rece implements Runnable{

private DatagramSocket ds;
public Rece(DatagramSocket ds){
this.ds = ds;
}
@Override
public void run() {
try {
while(true){
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip =dp.getAddress().getHostName();
int port = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+"的"+port+"端口,發來了電報:"+data);
}
} catch (Exception e) {
e.printStackTrace();
}
}

}
           

TCP實作

package com.heima.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

public class SocketDemo {

	public static void main(String[] args) {

		try {
			// 1.建立用戶端的socket服務,建立和主機,端口的socket流
			Socket socket = new Socket("127.0.0.1", 10006);
			new Thread(new Read(socket)).start();
			new Thread(new Write(socket)).start();
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

class Read implements Runnable {

	private Socket socket;

	public Read(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		// 3.得到資料
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			String line = null;
			while ((line = br.readLine()) != null) {
				System.out.println("伺服器" + socket.getInetAddress().getHostName()
						+ "端口:" + socket.getPort() + "發來了封包:"+line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

class Write implements Runnable {

	private Socket socket;

	public Write(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
			//printWriter的優勢:
			//1.位元組和字元流都可以接受
			//2.自動換行和重新整理緩沖流
			PrintWriter out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
			String line = null;
			while ((line = br.readLine()) != null) {
				if("exit".equals(line))break;
				out.println(line);
			}
			socket.shutdownOutput();
			// 流是通過socket建立的,關閉socket,流也被關閉的
			socket.close();//關閉後傳回-1
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			try {
				br.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

}
           
package com.heima.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerSocketDemo {

	public static void main(String[] args) {

		try {
			// 1.建立socket服務,并監聽端口
			ServerSocket ss = new ServerSocket(10006);
			// 2.擷取連接配接的用戶端對象,沒有連接配接就會阻塞
			Socket socket = ss.accept();
			new Thread(new ServerRead(socket)).start();
			new Thread(new ServerWrite(socket)).start();
			// 關閉用戶端連接配接
			 //socket.close();
			// 4.關閉【一般伺服器不關】
			// ss.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

class ServerRead implements Runnable {

	private Socket socket;

	public ServerRead(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));
			String line = null;
			System.out.println(br.readLine());
			//readLine()讀到回車符結束
			while ((line = br.readLine()) != null) {
				System.out.println("用戶端"
						+ socket.getInetAddress().getHostName() + "端口:"
						+ socket.getPort() + "發來了封包:" + line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

class ServerWrite implements Runnable {

	private Socket socket;

	public ServerWrite(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			PrintWriter out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
			String line = null;
			while ((line = br.readLine()) != null) {
				if ("exit".equals(line))
					break;
				out.println(line);
			}
			socket.shutdownOutput();
			//socket.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
           

------- android教育訓練  、 java教育訓練 、期待與您交流! ----------