一、概述
Socket类是Java运行clientTCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信。
Socket类的方法会建立和销毁连接,设置各种Socket选项。
ServerSocket类是Java执行server端操作的基础类,该类执行于server,监听入站TCP连接。每一个socketserver监听server的某个port。当远程主机的client尝试连接此port时。server就被唤醒。并返回一个表示两台主机之间socket的正常Socket对象。
二、什么是TCP?
TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP通信分为client和server端,相应的对象是各自是Socket和ServerSocket。
当一台计算机须要与还有一台远程计算机连接时,TCP协议会让他们建立一个连接:用于发送和接收数据的虚拟链路。
TCP协议负责收集信息包。并将其按适当的次序放好传送。在接收端收到后再将其正确的还原。
为了保证数据包在传送中准确无误,TCP使用了重发机制:当一个通信实体发送一个消息给还有一个通信实体后须要收到还有一个实体的确认信息。假设没有收到确认信息,则会再次重发刚才发送的信息。
三、TCP通信
1、构造函数
Socket类实现client套接字,通过构造函数能够指定希望连接的主机和port。
主机能够指定为InetAddress或String,port始终指定为0到65535之间的int值。
Socket s=new Socket("127.0.0.1", 10001);//创建一个流套接字并将其连接到指定主机上的指定port号
ServerSocket类实现server套接字。
server套接字等待请求通过网络传入。它基于该请求运行某些操作。然后向请求者返回结果。
ServerSocket ss=new ServerSocket(10001);//创建绑定到特定port的server套接字
2、样例:TCP文件复制
client:
public class ClientDemo { public static void main(String[] args) throws UnknownHostException, IOException { Socket s=new Socket("127.0.0.1", 10004); BufferedReader buf = new BufferedReader(new FileReader("C:\\Users\\Administrator\\Desktop\\1.txt")); String line=null; /*PrintWriter out=new PrintWriter(s.getOutputStream(),true); while((line=buf.readLine())!=null) { out.println(line); } */ BufferedWriter out=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); while((line=buf.readLine())!=null) { out.write(line); out.newLine(); out.flush(); } s.shutdownOutput(); BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); String str=in.readLine(); System.out.println(str); s.close(); buf.close(); } }
server端:
public class ServerDemo { public static void main(String[] args) throws IOException { ServerSocket ss=new ServerSocket(10004); Socket s=ss.accept(); BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); String line=null; /*PrintWriter buf=new PrintWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\2.txt"),true); while((line=in.readLine())!=null) { buf.println(line); }*/ BufferedWriter buf=new BufferedWriter(new FileWriter("C:\\Users\\Administrator\\Desktop\\2.txt")); while((line=in.readLine())!=null) { buf.write(line); buf.newLine(); buf.flush(); } PrintWriter out=new PrintWriter(s.getOutputStream(),true); out.println("传输成功!"); ss.close(); buf.close(); } }
四、Socket在浏览上的应用
我们能够在Eclipse中编写server端。然后利用浏览器进行訪问。
eg、server端代码为:
public class SocketServer { public static void main(String[] args) throws IOException { ServerSocket server=new ServerSocket(11000); Socket client=server.accept(); PrintWriter out=new PrintWriter(client.getOutputStream(),true); out.println("你好! "); server.close(); } }
然后打开IE浏览器,在地址中输入http://192.168.1.120:11000/(192.168.1.120为本机IP地址)。结果显示为:
在正常的应用中,浏览器是向Tomacatserver发出请求。以得到网页图片等资源。而tomca就是用Java写的server端软件。
如今我们编写server端为:
public class SocketServer { public static void main(String[] args) throws IOException { ServerSocket server=new ServerSocket(11000); Socket client=server.accept(); PrintWriter out=new PrintWriter(client.getOutputStream(),true); BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); String line=null; while((line=in.readLine())!=null) System.out.println(line); out.println("你好! "); server.close(); } }
然后在利用浏览器訪问。能够看到浏览器(client)发给server端的请求头数据为:
利用上述原理。我们能够自己编写类似IE的浏览器端(client)软件。首先在Tomcat的安装文件夹C:\apache-tomcat-7.0.62\webapps\myweb中加入一个demo.html资源,然后编写client。代码例如以下:
public class ClientDemo { public static void main(String[] args) throws UnknownHostException, IOException { Socket s=new Socket("192.168.1.120",8080); PrintWriter out=new PrintWriter(s.getOutputStream(),true); //将请求头发给server out.println("GET /myweb/demo.html HTTP/1.1"); out.println("Accept:*/*"); out.println("Host: 192.168.1.120:11000"); out.println("Connection: Keep-Alive"); //输出空行,此步骤不可少 out.println(); BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); String line=null; //返回server的响应文件 while((line=in.readLine())!=null) { System.out.println(line); } s.close(); } }
接下来,启动Tomcat。即双击C:\apache-tomcat-7.0.62\bin中startup.bat文件。然后执行上述client代码,此时能够看到Tomacat返回的响应数据: