在客户/服务器通信模式中,客户端需要主动创建与服务器连接的Socket(套接字),服务器端收到了客户端的连接请求,也会创建与客户连接的Socket。Socket可看做是通信连接两端的收发器,服务器与客户端都通过Socket来收发数据。
一、构造Socket
Socket的构造方法有以下几种重载形式:
1、Socket()
通过系统默认类型的 SocketImpl 创建未连接套接字
2、Socket(InetAddress address,int port) throws UnknownHostException,IOException
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
3、Socket(InetAddress address,int port,InetAddress localAddr,int localPort)
创建一个套接字并将其连接到指定远程地址上的指定远程端口。
4、Socket(String host,int port)
创建一个流套接字并将其连接到指定主机上的指定端口号。
5、Socket(String host,int port,InetAddress localAddr,int localPort)
创建一个套接字并将其连接到指定远程主机上的指定远程端口。
举例:
下面程序的PortScanner类能够扫描主机上从1到1024之间的端口,判断这些端口是否已经被服务器程序监听。PortScanner类的scan()方法在一个for循环中创建Socket对象,每次请求连接不同的端口,如果Socket对象创建成功,就表明在当前端口有服务器程序监听。
PortScanner.java
import java.io.IOException; import java.net.Socket; import javax.annotation.PostConstruct; public class PortScanner { public static void main(String[] args) { String host="localhost"; if(args.length>0) host=args[0]; new PortScanner().scan(host); } public static void scan(String host){ Socket socket=null; for(int port=1;port<1024;port++){ try { socket=new Socket(host, port); System.out.println("There is a server on port"+port); } catch (IOException e) { System.out.println("Can't connect to port"+port); }finally { try { if(socket!=null){ socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } } }
1.1、设定等待建立连接的超时时间
1.2 设定服务器地址
1.3 设置客户端地址
1.4 客户连接服务器时可能抛出的异常
ConnectTester.java
运行结果为:localhost/127.0.0.1:135: 13msimport java.io.IOException; import java.net.BindException; import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketTimeoutException; import org.omg.CORBA.portable.UnknownException; public class ConnectTester { public static void main(String[] args) { String host="localhost"; int port=135; if(args.length>1){ host=args[0]; port=Integer.parseInt(args[1]); } new ConnectTester().connect(host,port); } public static void connect(String host,int port) { SocketAddress remoteAddr=new InetSocketAddress(host, port); Socket socket=null; String result=""; try { long begin=System.currentTimeMillis(); socket=new Socket(); socket.connect(remoteAddr, 1000); long end=System.currentTimeMillis(); result=(end-begin)+"ms"; } catch (BindException e) { result="Local address and port can't be binded"; }catch (UnknownException e) { result="Unknow Host"; }catch (ConnectException e) { result="Connection Refused"; }catch (SocketTimeoutException e) { result="TimeOut"; }catch (IOException e) { result="failure"; }finally{ try { if(socket!=null) socket.close(); } catch (IOException e2) { e2.printStackTrace(); } } System.out.println(remoteAddr+": "+result); } }
SimpleServer.java
import java.io.IOException; import java.net.ServerSocket; public class SimpleServer { public static void main(String[] args) throws Exception{ ServerSocket serverSocket=new ServerSocket(8003,2); Thread.sleep(360000); } }
SimpleClient.java
import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; public class SimpleClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s1=new Socket("localhost", 8003); System.out.println("第一次连接成功"); Socket s2=new Socket("localhost", 8003); System.out.println("第二次连接成功"); Socket s3=new Socket("localhost", 8003); System.out.println("第三次连接成功"); } }
先运行“java SimpleServer”命令,启动服务器程序,再运行“java SimpleClient”命令,启动客户程序,客户端会得到
结果为: