Java Socket主要有普通Socket和NioSocket
普通Socket又分为 ServerSocket和Socket两种,ServerSocket用于服务端,通过accept方法监听请求,然后返回给Socket。
客户端直接用Socket发起请求并传输数据。
Clinet
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client{
public static void main(String[] args) {
String msg = "Client Data";
try {
Socket socket = new Socket("127.0.0.1",10000);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw.println(msg);
pw.flush();
String line = is.readLine();
System.out.println("received from Server: " + line);
pw.close();
is.close();
socket.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
Server
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server{
public static void main(String args[]){
try {
ServerSocket server = new ServerSocket(10000);
Socket socket = server.accept();
BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = is.readLine();
System.out.println("receive:"+line);
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println("received data:"+line);
pw.flush();
pw.close();
is.close();
socket.close();
server.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
java.nio包是Java在1.4之后增加的,用来提高I/O操作的效率。在nio包中主要包括以下几个类或接口:
Buffer:缓冲区,用来临时存放输入或输出数据。
Charset:用来把Unicode字符编码和其它字符编码互转。
Channel:数据传输通道,用来把Buffer中的数据写入到数据源,或者把数据源中的数据读入到Buffer。
Selector:用来支持异步I/O操作,也叫非阻塞I/O操作。
nio包中主要通过下面两个方面来提高I/O操作效率:
通过Buffer和Channel来提高I/O操作的速度。
通过Selector来支持非阻塞I/O操作。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.net.SocketOption;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Handler;
public class NIOSocket {
public static void main(String[] args) throws Exception {
//创建SeverSocketChannel,监听8080
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress(8080));
//设置非阻塞
ssc.configureBlocking(false);
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT);
Handler handler = new Handler(1024);
while(true){
if(selector.select(3000) == 0){
System.out.println("等待连接超时。。");
continue;
}
System.out.println("处理请求。。");
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while(keyIter.hasNext()){
SelectionKey key = keyIter.next();
try {
if(key.isAcceptable()){
handler.handleAccept(key);
}
if(key.isReadable()){
handler.handleRead(key);
}
} catch (Exception e) {
// TODO: handle exception
}
keyIter.remove();
}
}
}
private static class Handler{
private int bufferSize = 1024;
private String localCharset = "utf-8";
public Handler(){}
public Handler(int bufferSize){
this(bufferSize,null);
}
public Handler(String LocalCharset){
this(-1,LocalCharset);
}
public Handler(int bufferSize,String localCharset){
if(bufferSize > 0)
this.bufferSize = bufferSize;
if(localCharset != null)
this.localCharset = localCharset;
}
public void handleAccept(SelectionKey key)throws IOException{
SocketChannel sc = ((ServerSocketChannel)key.channel()).accept();
sc.configureBlocking(false);
sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufferSize));
}
public void handleRead(SelectionKey key)throws IOException{
SocketChannel sc = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer)key.attachment();
buffer.clear();
if(sc.read(buffer) == -1){
sc.close();
}else{
buffer.flip();
String receivedString = Charset.forName(localCharset).newDecoder()
.decode(buffer).toString();
System.out.println("received form client: " + receivedString);
String sendString = "received data: " + receivedString;
buffer = ByteBuffer.wrap(sendString.getBytes(localCharset));
sc.write(buffer);
sc.close();
}
}
}
}