什么也别说先撸一个服务器实现以下几个步骤
// 代码详情-实现单个socket服务器
package socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerTest {
public static void main(String[] args) throws IOException{
ServerSocket s = new ServerSocket(8189);
Socket incoming = s.accept();
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
try (Scanner in = new Scanner(inStream)){
PrintWriter out = new PrintWriter(outStream,true);
out.println("hello client");
boolean done = false;
while (!done && in.hasNextLine()){
String line = in.nextLine();
out.println("Echo:" + line);
if(line.trim().equals("BYE")) done = true;
}
}
}
}
测试
ServerSocket (int port ) 创建一个监听端口的套接字 Socket accept() 等待链接。该方法阻塞当前线程直到建立连接为止,该方法返回一个socket对象,通过此对象与连接中的客户端进行通信 void close() 关闭套接字
package socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ThreadedEchoServer {
public static void main(String[] args) {
try {
int i =1;
ServerSocket s= new ServerSocket(8189);
while (true){
Socket incomeing = s.accept();
System.out.println("Spwaning"+ i );
Runnable r = new ThreadedEchoHandler(incomeing);
Thread t = new Thread(r);
t.start();
i++;
}
}catch (IOException error){
error.printStackTrace();
}
}
}
```ThreadedEchoHandler.java
package socket;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
class ThreadedEchoHandler implements Runnable{
private Socket incoming;
public ThreadedEchoHandler(Socket i){
incoming = i;
}
public void run() {
try {
try {
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream,true);
out.println("hello client");
boolean done = false;
while (!done && in.hasNextLine()){
String line = in.nextLine();
out.println("Echo:" + line);
if(line.trim().equals("BYE")) done = true;
}
}finally {
incoming.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
测试
当我们一个client连接一个套接字时,当前线程会被阻塞直到建立连接或者超时为止 同样的当通过套接字读写数据时,当前线程也会被阻塞或者直到超时 对于这种阻塞我们无法通过interrupt来解除阻塞 中断套接字
对于这种情况可以使用java.nio提供的一个特性----SocketChannel类 SocketChannel chananel = SocketChannel..open(new InetSocketAdress(host,port))
使用SocketChannel来打开一个通道如果线程阻塞将以抛出异常结束而不是陷入阻塞
thread.interrupt(); 线程通过interupt() 把中断标志位设置为true 线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true) 使用Thread.currentThread().isInterrupted()方法检测
顺便再提一下其他和线程阻塞有关方法
sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。