Java Socket和ServerSocket

Java Socket和ServerSocket 网络编程

转载请注明出处:http://blog.csdn.net/u012891600/article/details/52444146

在java和android面试中我们经常会被问起Socket编程,那么什么才是Socket?

  • 什么才是Socket?
  • 两个应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket
  • Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将
    这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。
  • Socket通常用来实现client-server连接,建立连接时所需的寻址信息为远程计算机的IP地址和端口号(Port Number)
  • Socket的通讯过程
public class TestClientSocket {

    public static void main(String[] args) {
        try {
        //第一步 创建Socket对象
            Socket s = new Socket("localhost",8888);
            //子线程实现通讯
            new Thread(new saveFile(s)).start();

        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

class saveFile implements Runnable{

    private Socket s;

    public saveFile(Socket s) {
        super();
        this.s = s;
    }

    @Override
    public void run() {
        ObjectInputStream oos;
        BufferedOutputStream bos =null;
        try {
        //第二步连接到Socket的输入/输出流
            oos = new ObjectInputStream(s.getInputStream());
            String fileName = oos.readUTF();
            long fileLength = oos.readLong();
            System.out.println("文件名:"+fileName+"  长度:"+fileLength);
            File file = new File("/Users/dpb/Desktop/save/"+fileName);
            while(file.exists()){
                file = new File("/Users/dpb/Desktop/save/"+"1"+file.getName());
            }
            bos = new BufferedOutputStream(new FileOutputStream(file));
            byte b[] = new byte[1024];
            int sum = 0 ; //已经读取的长度
            int num = 0 ; 
            //3.按照一定的协议对socket进行读/写操作;
            while(sum < fileLength){
                if(sum+1024 > fileLength){
                    num = oos.read(b,0,(int)(fileLength-sum));
                }else{
                    num = oos.read(b);
                }
                sum += num;
                bos.write(b, 0, num);

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
            //4.关闭流;
                bos.close();
                System.out.println("数据下载完成....");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }


    }

}
  • 3.掌握TCP Socket 通信模型
    1.通信原理
    这里写图片描述
    2.通信模型
    这里写图片描述
    3.网络传输中注意事项
    服务器读取网络上的远程数据时不应该以读到-1作为结束,应该用先前客户端告知的文件大小与
    累计接收到的数据大小比较来判断循环是否应该结束.
    客户端关闭流会让服务器读到-1,如果客户端在上传完文件后还要给服务器发其他信息,服务器就不
    能结束循环了,直到客户端close掉输出流
    关闭任何关联到Socket上的流,都会将Socket自动关闭掉;
    关闭Socket将会自动关闭关联在上面的流.
    关闭高级流会递归的关闭它包装的低级流.
    4.服务器端多线程向多客户端写文件
    ServerFile
    等待新连接的客户端,启动线程向客户端写出指定文件
    FileThread
    线程类, ObjectOutputStream:writeLong()告知客户端文件大小,
    OutputStream:write()向客户端写文件
    ClientFile
    从线程类对象获知文件大小ObjectInputStream:readLong(),
    读线程类对象发过来的文件数据,并写出到本地文件中

  • *服务端编程
    public class TestServerSocket {

    public static void main(String[] args) {
    try {
    //建立服务端socket对象
    ServerSocket ss = new ServerSocket(8888);
    while(true){
    Socket s = ss.accept(); //阻塞事件
    System.out.println(s.getInetAddress().getHostName()+”连接了,准备下载数据…”);
    new Thread(new FileThread(s)).start();
    }
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    }

}

/**
* 服务端 把资源写入Socket
* @author dpb
*
*/
class FileThread implements Runnable{

private Socket s;

public FileThread(Socket s) {
    super();
    this.s = s;
}

@Override
public void run() {
    BufferedInputStream bis = null;
    File file = new File("/Users/dpb/Desktop/作业.zip");
    ObjectOutputStream oos = null;
    try {
        bis = new BufferedInputStream(new FileInputStream(file));
        oos = new ObjectOutputStream(s.getOutputStream());
        oos.writeUTF(file.getName());
        oos.writeLong(file.length());
        byte b[] = new byte[1024];
        int num = 0;
        while((num = bis.read(b)) != -1){
            oos.write(b,0,num);
        }
        oos.flush();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        try {
            bis.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

}
- *通信的三种方式

方式一
    OutputStream(write())
    InputStream(read())
方式二
    BufferedWriter(write(),注意newLine(),flush()) PrintWriter(println())
    BufferedReader(readLine())
方式三
    ObjectInputStream(readObject())
    ObjectOutputStream(writeObject())
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值