socket
服务端
1.创建一个特定端口的ServerSocket
2.监听端口的入站连接(阻塞),直到客户端尝试连接
3.服务端和客户端根据已协商的协议交互
4.服务器或客户端关闭连接
客户端
1.创建socket连接指定端口和地址
2.服务端和客户端根据已协商的协议交互
3.客户端关闭连接
单线程服务端
ServerSocket serverSocket=new ServerSocket(8888) ;
while (true) {
Socket conection=serverSocket.accept();
OutputStream out = conection.getOutputStream();
Writer writer=new OutputStreamWriter(out,"utf-8");
Date date=new Date();
writer.write(date.toLocaleString());
writer.flush();
conection.close();
}
客户端
try (Socket socket=new Socket("127.0.0.1", 8888)) {
InputStream in=socket.getInputStream();
BufferedReader reader=new BufferedReader(new InputStreamReader(in, "utf-8"));
StringBuilder stringBuilder=new StringBuilder();
String line = null ;
while ((line=reader.readLine()) != null) {
stringBuilder.append(line);
}
System.out.println(stringBuilder.toString());
} catch (IOException e) {
System.out.println( e);
}
2017-7-11 22:55:57
多线程服务端
ServerSocket server=new ServerSocket(8888);
while (true) {
Socket socket=server.accept();
new Thread(
() ->{
try {
OutputStream out = socket.getOutputStream();
Writer writer=new OutputStreamWriter(out,"utf-8");
Date date=new Date();
writer.write(date.toLocaleString());
writer.flush();
} catch (IOException e) {
System.out.println(e);
}finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
).start();
}
服务端socket选项
1.SO_TIMEOUT:等待入站连接时间(毫秒)
public void setSotimeout(int timeout);
2.SO_RCVBUF:设置接受客户端缓冲区大小(需要在服务端绑定端口前设置)
public void setReceiveBufferSize(int size);
try (ServerSocket serverSocket=new ServerSocket(8888)) {
serverSocket.setSoTimeout(3000);
try {
Socket accept=serverSocket.accept();
accept.close();
} catch (SocketTimeoutException e) {
System.out.println(" accept is error " + e);
}
} catch (Exception e) {
System.out.println(e);
}
accept is error java.net.SocketTimeoutException: Accept timed out
channel
基于通道的客户端
SocketAddress socketAddress=new InetSocketAddress("127.0.0.1", 8888);
SocketChannel client=SocketChannel.open(socketAddress);
ByteBuffer byteBuffer=ByteBuffer.allocate(100);
WritableByteChannel out=Channels.newChannel(System.out);
while (true) {
int read=client.read(byteBuffer);
if (read > 0) {
byteBuffer.flip();
out.write(byteBuffer);
byteBuffer.clear();
}
if (read == -1)
break;
}
client.close();
基于通道的服务端
byte[] send=new byte[95 * 2];
for (byte i=' '; i <= '~'; i++) {
send[i - ' ']=i;
send[i + 95 - ' ']=i;
}
ServerSocketChannel serverChannel;
Selector selector;
try {
serverChannel=ServerSocketChannel.open();
ServerSocket server=serverChannel.socket();
server.bind(new InetSocketAddress(8888));
serverChannel.configureBlocking(false);
selector=Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
System.out.println(e);
return;
}
while (true) {
try {
selector.select();
} catch (IOException e) {
e.printStackTrace();
break;
}
Set<SelectionKey> selectionKeys=selector.selectedKeys();
Iterator<SelectionKey> iterator=selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key=iterator.next();
iterator.remove();
try {
if (key.isAcceptable()) {
ServerSocketChannel server=(ServerSocketChannel) key.channel();
SocketChannel clientChannel=server.accept();
clientChannel.configureBlocking(false);
SelectionKey clientKey=clientChannel.register(selector, SelectionKey.OP_WRITE);
ByteBuffer buffer=ByteBuffer.allocate(74);
buffer.put(send, 0, 72);
buffer.put((byte) '\r');
buffer.put((byte) '\n');
buffer.flip();
clientKey.attach(buffer);
} else if (key.isWritable()) {
SocketChannel client=(SocketChannel) key.channel();
ByteBuffer buffer=(ByteBuffer) key.attachment();
if (!buffer.hasRemaining()) {
buffer.rewind();
int first=buffer.get();
buffer.rewind();
int postion=first - ' ' + 1;
buffer.put(send, postion, 72);
buffer.put((byte) '\r');
buffer.put((byte) '\n');
buffer.flip();
}
client.write(buffer);
}
} catch (IOException e) {
key.cancel();
try {
key.channel().close();
} catch (Exception ex) {
System.out.println(ex);
}
e.printStackTrace();
}
}
}
}