Java socket ,多客戶端同時與服務端不停的交換數據

    今天終於有時間來實踐一下Java socket的使用方法了,須要注意幾個問題: java

(1)、使用socket.getInputStream 讀取數據時,該方法是阻塞方法,即若是管道流中沒有數據時,使用inputStream.read(byte)是會一直阻塞,因此若是想要使用inputStream.read(new byte[]) > 0 來結束 服務器

循環是行不通的; socket

(2)、因爲個人目的是不停的交互數據,因此不能IO流關閉,也不能把socket會話關閉,不然數據交換就會中止。 ide

貼代碼作記錄: this

一、服務端代碼: .net

package com.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.base.Constant;

public class ServerMain {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		System.out.println("ServerSocket Begin........");
		int num = 0;
		try {
				serverSocket = new ServerSocket(Constant.PORT);
				//使用循環方式一直等待客戶端的鏈接
				while(true){
					num ++;
					Socket accept = serverSocket.accept();
					//啓動一個新的線程,接管與當前客戶端的交互會話
					new Thread(new ServerThread(accept),"Client "+num).start();
				}
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try {
				serverSocket.close();
				System.out.println("---->  serverSocket closed.");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
/**
 * @author JCC
 * 服務器處理客戶端會話的線程
 */
class ServerThread implements Runnable {
	
	Socket socket = null;
	public ServerThread(Socket socket){
		System.out.println("Create a new ServerThread...");
		this.socket = socket;
	}

	@Override
	public void run() {
		InputStream in = null;
		OutputStream out = null;
		try {
			in = socket.getInputStream();
			out  = socket.getOutputStream();
			//使用循環的方式,不停的與客戶端交互會話
			while(true){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//處理客戶端發來的數據
				doRead(in);
				System.out.println("send Message to client.");
				//發送數據回客戶端
				doWrite(out);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 讀取數據
	 * @param in
	 * @return
	 */
	public boolean doRead(InputStream in){
		//引用關係,不要在此處關閉流
		try {
			byte[] bytes = new byte[in.available()];
			in.read(bytes);
			System.out.println("line:"+new String(bytes).trim());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return true;
	}
	
	/**
	 * 寫入數據
	 * @param out
	 * @return
	 */
	public boolean doWrite(OutputStream out){
		//引用關係,不要在此處關閉流
		try {
			out.write("welcome you client.".getBytes());
			out.flush();		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}
}

 

二、客戶端代碼: 線程

package com.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import com.base.Constant;

class ClientMain {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Socket socket = null;
		System.out.println("ClientSocket Begin........");
		try {
			for(int i = 0;i<5;i++){
				socket = new Socket(Constant.SERVER_IP,Constant.PORT);
				new Thread(new ClientThread(socket,i),"ClientThread "+i).start();
			}
		    
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
}

/**
 * 客戶端線程
 * @author JCC
 *
 */
class ClientThread implements Runnable{
	Socket socket = null;
	int id = 0;
	public ClientThread(Socket socket,int id){
		this.socket = socket;
		this.id = id;
	}
	@Override
	public void run() {
		OutputStream out = null;
		InputStream in = null;
		System.out.println("Begin to Chat to server...");
		try {
			out = socket.getOutputStream();
			in = socket.getInputStream();
			//循環發送與服務端不停的交互數據
			while(true){
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				doWrite(out);
				System.out.println("begin read message from server.");
				doRead(in);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally{
			try {
				in.close();
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 讀取服務端數據
	 * @param in
	 * @return
	 */
	public static boolean doRead(InputStream in){
		//引用關係,不要在此處關閉流
		byte[] bytes = new byte[1024];
		try {
			in.read(bytes);
			System.out.println("line:"+new String(bytes).trim());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return true;
	}
	
	/**
	 * 發送數據到服務端
	 * @param out
	 * @return
	 */
	public boolean doWrite(OutputStream out){
		//引用關係,不要在此處關閉流
		String line = "Hello server, I am client = "+id +"\n";
		line = line +"I want you to do something for me";
		try {
			out.write(line.getBytes());
			out.flush();		
		} catch (IOException e) {
			e.printStackTrace();
		}
		return true;
	}
}

 

三、常量類: code

package com.base;

public interface Constant {

	public static final  String SERVER_IP = "192.168.1.44";
	public static final int PORT = 4567; 
}

 

執行結果: server

(1)服務端結果: get

ServerSocket Begin........
Create a new ServerThread...
Create a new ServerThread...
Create a new ServerThread...
Create a new ServerThread...
Create a new ServerThread...
line:
send Message to client.
line:
send Message to client.
line:
send Message to client.
line:Hello server, I am client = 3
I want you to do something for me
send Message to client.
line:Hello server, I am client = 4
I want you to do something for me
send Message to client.
line:Hello server, I am client = 0
I want you to do something for me
send Message to client.
line:Hello server, I am client = 1
I want you to do something for me
send Message to client.
line:Hello server, I am client = 2
I want you to do something for me
send Message to client.
line:
send Message to client.
line:
send Message to client.
line:Hello server, I am client = 0
I want you to do something for me
send Message to client.
line:Hello server, I am client = 1
I want you to do something for me
send Message to client.
line:Hello server, I am client = 2
I want you to do something for me
send Message to client.
line:Hello server, I am client = 3
I want you to do something for me
send Message to client.
line:Hello server, I am client = 4
I want you to do something for me
send Message to client.
line:Hello server, I am client = 0
I want you to do something for me
send Message to client.

(2)客戶端結果:

ClientSocket Begin........
Begin to Chat to server...
Begin to Chat to server...
Begin to Chat to server...
Begin to Chat to server...
Begin to Chat to server...
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
line:welcome you client.
begin read message from server.
相關文章
相關標籤/搜索