声明:本文为原创,如需转载请说明出处:http://www.cnblogs.com/gudu1/p/7669175.html
首先为什么要写这个呢?因为在几个月之前我还使用Socket做一个小项目,而在今天我回想起Socket的操作细节,在我脑海里使劲挖掘Socket的痕迹,竟然丝毫没有找到,我很苦恼,所以立即写了一个小Demo来记录一下,有些东西长时间不用肯定要忘的,要知道人的脑容量是有限的,跟电脑缓存一样,不够用的时候会把那些不用的占内存的给释放掉, 就到这吧,说正题。
Socket 和 ServerSocket 的官方API解释:
Socket : 此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
ServerSocket:此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
套接字的实际工作由 SocketImpl
类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。
在这个Demo中我使用了java.net包下的两个类:Socket 和 ServerSocket ,使用到的自定义类有3个:Service 、 Client 、ServiceThread,下面配合代码来解释一下
ServiceThread.java ,就把它当做一个服务器处理程序就好了
import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.io.IOException;import java.io.*;public class ServiceThread implements Runnable { ???Socket s = null; ???????public ServiceThread(Socket socket) { // ① ???????super(); ???????this.s = socket; ???} ???@Override ???public void run() { ???????String ip = s.getInetAddress().getHostName(); // ② ???????System.out.println("ip:"+ip); ????????try{ ???????????InputStream is = s.getInputStream(); // ③ ???????????byte[] buf = new byte[1024]; ???????????int len = 0; ???????????????File file = new File("D:/heheCopy.java"); // ④ ???????????OutputStream os = new FileOutputStream(file); ???????????System.out.println("开始上传"); ???????????while((len = is.read(buf)) != -1){ // ⑤ ???????????????os.write(buf,0,len); ?// ⑥ ???????????} ???????????????System.out.println("上传完毕"); ???????????is.close(); ???????????os.close(); ???????} catch (Exception e){ ???????????e.printStackTrace(); ???????} ???????????}}
① :类只有一个构造函数,参数是Socket对象(即一个用户),因为在服务器和客户端是通过 I/O 流来交互,所以服务器端要获取客户端的IO对象(即输入输出流)。
②: 获取客户端的IP地址
③: 获取客户端的输入流,
④: 创建一个File对象,并指定客户端传输过来的数据存放的位置,如果不存在该文件就自动创建
⑤: 开始从流中读取数据,并存放在byte数组缓冲区中,在客户端的输出流未写入之前此方法一直处于阻塞状态(即等待状态)
⑥: 开始写入服务器本地文件
Client.java ,当做一个客户端
public class Client { ???public static void main(String[] args) throws Exception { ???????Socket s = new Socket("127.0.0.1", 10001); ?// ① ???????InputStream is = new FileInputStream("D:/hehe.java"); // ② ???????byte[] buf = new byte[1024]; ???????int len = 0; ???????while((len = is.read(buf))!=-1){ ???????????s.getOutputStream().write(buf,0,len); // ③ ???????} ???????s.shutdownOutput(); // ④ ???????System.out.println("读取完毕"); ???????is.close(); ???}}
①: 创建 Socket 对象,传入要连接服务器的 IP 和 端口
②: 创建一个输入流对象读取要上传的文件路径
③: 获取 Socket 输出流对象并将读取到的数据写入输出流中
④: 任何以前写入的数据都将被发送,如果不调用这个方法,那么在服务器端就不会知道数据已经传输完毕,将继续调用此 Socket 输入流的 read 方法,那么此时客户端只是一个Java程序,已经执行完毕,虚拟机将释放资源,这时,此Socket已经被 close掉,程序将抛出 SocketException 异常。
Serivce.java ,服务器
public class Service{ ???public static void main(String[] args)throws Exception{ ???????ServerSocket ss = new ServerSocket(10001); // ① ???????while(true){ ???????????Socket s = ss.accept(); // ② ???????????new Thread(new ServiceThread(s)).start(); ?// ③ ???????} ???}}
①: 创建服务器对象,指定该服务器的端口号
②: 获得请求连接到该服务器的客户端对象Socket
③: 启动服务器处理程序线程,因为程序是无限循环,所以每当一个客户端连接进来都会创建一个新的线程
The End。。。。。
Socket简单实现数据交互及上传
原文地址:http://www.cnblogs.com/gudu1/p/7669175.html