思路
基于TCP协议,手写服务器,接收客户端请求并且做出响应
编码
底层通信时BIO,所以需要使用多线程
而且服务器端socket总领全局,不和任何一个socket建立连接,当有客户端请求时,分配一个新的socket与客户端通信。
客户端
package server;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* tcp协议进行通信时,需要区分客户端和服务器端
*/
public class clientNonBlock {
public static void main(String[] args) throws IOException {
//1、获取通信用的socket
Socket socket = new Socket();
//2、指定连接的服务器,tcp是基于连接的通信
//~~~~~~~~~~~~所以如果没有连上这里会阻塞~~~~~~
socket.connect(new InetSocketAddress("localhost",8080));
System.out.println("已建立连接");
new Thread(new Runnable() {//写功能
@Override
public void run() {
while (true) {
//3、写出数据(通过socket提供的输出流,将数据写到对端socket)
try {
OutputStream outputStream = socket.getOutputStream();
String s = "client>" + new BufferedReader(new InputStreamReader(System.in)).readLine();
outputStream.write(s.getBytes());
//socket.shutdownOutput();一直写的情况下不能关闭,关闭就没有输出流了
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
byte[] buffer = new byte[1014];
int len = -1;
//while(true) {
try {
InputStream inputStream = socket.getInputStream();
while ((len = inputStream.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, len));
}
//socket.shutdownInput();
} catch (IOException e) {
e.printStackTrace();
}
}
//}
}).start();
}
}
服务器
package server;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
/**
* tcp协议服务器端
*/
public class serverNonBlock {
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost",8080));
while(true){
//服务器端socket接收请求
Socket socket = serverSocket.accept();
//开启一个线程处理请求
new Thread(new handler(socket)).start();
}
}
}
/**
* 处理客户端请求线程
*/
class handler implements Runnable{
private Socket socket = null;
private InputStream is = null;
private OutputStream os = null;
private SocketAddress client = null;
private String clientMessage = null;
private boolean flag = false;
public handler(Socket socket) throws IOException {
this.socket = socket;
this.client = socket.getRemoteSocketAddress();
this.is = socket.getInputStream();
this.os = socket.getOutputStream();
}
@Override
public void run() {
new Thread(new Runnable() { //接收请求线程
@Override
public void run() {
//读取客户端发送的请求
try {
byte[] buffer = new byte[1024];
int len = -1;
while((len=is.read(buffer))!=-1){
String s = new String(buffer, 0, len);
System.out.println(s);
clientMessage = s;
flag = true;
}
//accept.shutdownInput();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
while(true) {
if(!flag){
Thread.yield();
}else {
String server_msg = "server>" + clientMessage;
os.write(server_msg.getBytes());
flag = false;
}
}
//accept.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}