使用Socket
客户端Socket仅实现前四个功能。服务器端实现全部功能。
Telnet研究协议
用Socket从服务器读取
package Ch8;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
public class DaytimeClient {
public static void main(String[] args) {
String hostname = args.length>0?args[0]:"time.nist.gov";
Socket socket = null;
try{
//连接失败,抛出IOException异常
socket = new Socket(hostname,13);
//超时时间
socket.setSoTimeout(15000);
InputStream in = socket.getInputStream();
StringBuilder time = new StringBuilder();
InputStreamReader reader = new InputStreamReader(in,"ASCII");
for(int c = reader.read();c!=-1;c=reader.read()){
time.append((char)c);
}
System.out.println(time);
}catch (IOException ex){
System.err.println("ex");
}finally {
if(socket!=null){
try{
socket.close();
}catch (IOException ex){
}
}
}
}
}
/*58088 17-12-01 07:14:48 00 0 0 48.5 UTC(NIST) * */
用Socket写入服务器
package Ch8;
import java.io.*;
import java.net.Socket;
public class DictClient {
public static final String SERVER = "dict.org";
public static final int PORT = 2628;
public static final int TIMEOUT = 15000;
public static void main(String[] args) {
Socket socket =null;
try{
socket = new Socket(SERVER,PORT);
socket.setSoTimeout(TIMEOUT);
OutputStream out = socket.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer = new BufferedWriter(writer);
InputStream in = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
for(String word : args){
define(word,writer,reader);
}
writer.write("quit\r\n");
writer.flush();
}catch (IOException ex){
System.err.println(ex);
}finally {
{
if(socket!=null){
try{
socket.close();
}catch (IOException ex){
//
}
}
}
}
}
static void define(String word, Writer writer, BufferedReader reader) throws IOException, UnsupportedEncodingException{
writer.write("DEFINE eng-lat "+word + "\r\n");
writer.flush();
for(String line = reader.readLine(); line!=null; line = reader.readLine()){
if(line.startsWith("250")){return ;}
else if(line.startsWith("552")){
System.out.println("No definetion found for "+word);
return;
}else if(line.matches("\\d\\d\\d .*")) continue;
else if(line.trim().equals(".")) continue;
else System.out.println(line);
}
}
半关闭Socket
public void shutdownInput() throws IOException
public void shutdownOutput() throws IOException
构造和连接Socket
Socket是完成TCP连接的基础类。其他(URL,URLConnection,Applet)最终都会调用这个类的方法。Socket本身使用原生代码…
基本构造函数
//接受InetAddress或String作为主机名,1到65535作为端口值。
//无法解析主机名,抛出UnknownHostException
public Socket(String host, int port) throws UnknownHostException, IOException
public Socket(String host, int port) throws UnknownHostException, IOException
选择本地接口
public Socket(String host, int port, InetAddress interface, int localPort) throws UnknownHostException, IOException
public Socket(String host, int port, InetAddress interface, int localPort) throws UnknownHostException, IOException
构造但不连接
无参构造器,不连接。主要好处清理代码
//无参构造,没有连接,但也不是null。finally不必再检查null。
Socket socket = new Socket();
//Socket地址
SocketAddress address = new InetSocketAddress("localhost",1024);
//第二个参数设置timeout,0表示一直等待。
socket.connect(address,0);
Socket地址
SocketAddress类表示一个连接端点。空的抽象类。实际使用的是InetSocketAddress实例。
SocketAddress getRemoteSocketAddress();
SocketAddress getLocalSocketAddress();
InetSocketAddress提供一些get方法。
public final InetAddress getAddress()
public final int getPort()
public final String getHostName()
代理
public Socket(Proxy proxy)
//通常Socket使用的代理服务器由socksProxyHost和socksProxyPort系统属性控制。
//但这个构造函数可以指定代理服务器。传入Proxy.NO_PROXY,完全绕过代理,直接连接。防火墙不允许,会失败。
SocketAddress proxyAddress = new InetSocketAddress("myproxy.example.com",1080);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddress);
Socket s = new Socket(proxy);
SocketAddress remote = new InetSocketAddress("login.ibiblio.org",25);
s.connect(remote);
获取属性
//远程主机
public InetAddress getInetAddress()
public int getPort()
//本地主机
public InetAddress getLocalAddress()
public int getLocalPort()
//关闭和连接
isConnected()
isClosed()
isBound()
//toString()
设置Socket选项??用时再理解
Socket异常
//没有权限使用端口
public class BindException extends SocketException
//主机忙,没有进程监听端口,导致被拒绝。
public class ConnectException extends SocketException
//超时
public class NoRouteToHostException extends SocketException
//接受的数据违反TCP/IP规范
public class ProtocolException extends IOException