多線程技術
服務器接收到一個客戶的套接字後,就啓動一個專門爲該客戶服務的線程。
例題:客戶端輸入圓的半徑併發送給服務器,服務器把計算出的圓的面積返回給客戶。因此可以將計算量大的工作放在服務器端,客戶端負責計算量小的工作,實現客戶端-服務器交互計算來完成任務。
Server.java
package SocketClass.ServerThread;
import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
public static void main(String []args){
ServerSocket server = null;
ServerThread thread;
Socket you = null;
while (true){
try{
server = new ServerSocket(956);
}catch (Exception e){
System.out.println("正在監聽");//ServerSocket對象不能重複創建
}
try{
System.out.println("等待客戶呼叫");
you = server.accept();
System.out.println("客戶的地址:"+you.getInetAddress());
}catch (Exception e){
System.out.println("正在等待客戶");
}
if(you!=null){
new ServerThread(you).start();//爲每個客戶啓動一個專門的線程
}
}
}
}
class ServerThread extends Thread{
Socket socket;
DataOutputStream out = null;
DataInputStream in = null;
String s = null;
ServerThread(Socket t){
socket = t;
try{
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
}catch (Exception e){
}
}
public void run(){
while (true){
try{
double r =in.readDouble();//堵塞狀態,除非讀取到信息
double area = Math.PI*r*r;
out.writeDouble(area);
}catch (Exception e){
System.out.println("客戶離開");
return;
}
}
}
}
Client.java
package SocketClass.ServerThread;
import java.io.*;
import java.net.*;
import java.util.*;
public class Client {
public static void main(String []args){
Scanner scanner = new Scanner(System.in);
Socket mysocket = null;
DataInputStream in = null;
DataOutputStream out = null;
Thread readData;
Read read = null;
try{
mysocket = new Socket();
read = new Read();
readData = new Thread(read);
System.out.println("輸入服務器的IP:");
String IP=scanner.nextLine();
System.out.println("輸入端口號:");
int port = scanner.nextInt();
if(mysocket.isConnected()){
}else {
InetAddress address = InetAddress.getByName(IP);
InetSocketAddress socketAddress = new InetSocketAddress(address,port);
mysocket.connect(socketAddress);
in = new DataInputStream(mysocket.getInputStream());
out = new DataOutputStream(mysocket.getOutputStream());
read.setDataInputStream(in);
readData.start();
}
}catch (Exception e){
System.out.println("服務器已斷開"+e);
}
System.out.println("輸入圓的半徑(放棄請輸入N):");
while(scanner.hasNext()){
double radius = 0;
try{
radius = scanner.nextDouble();
}catch (Exception e){
System.exit(0);
}
try{
out.writeDouble(radius);
}catch (Exception e){
}
}
}
}
class Read implements Runnable{
DataInputStream in;
public void setDataInputStream(DataInputStream in){
this.in = in;
}
@Override
public void run() {
double result = 0;
while(true){
try{
result = in.readDouble();
System.out.println("圓的面積:"+result);
System.out.println("輸入圓的半徑(放棄請輸入N):");
}catch (Exception e){
System.out.println("與服務器已斷開"+e);
break;
}
}
}
}
本程序爲了調試方便,在建立套接字連接時,使用的服務器地址是127.0.0.1,如果服務器設置過有效的IP地址,就可以用有效的IP代替程序中的127.0.0.1.