java--Socket类和URL类

客户端

Socket类

Socket类底层的协议是TCP协议(传输控制协议,在传输层),可以给你想要获取数据的地址(ip地址)发送请求,然后获取数据。

方法:

构造函数

public Socket(String host,int port);//"ip地址",端口号,如:127.0.0.1,5000

发数据

public OutputStream getOutputStream();//返回的是OutputStream对象

收数据

public InputStream getInputStream();//返回InputStream对象

Socket执行IO流时会出现阻塞,也就是会阻塞其他的IO流的读写,因此要把与IO流相关的操作放在线程内执行(也就是放在run方法内,最好使用线程池的方式,这样做比较省资源)。

URL类

URL类也是用来给想要获取数的地址发送请求,以此来获得数据的,不过它获取的格式不同,需要写上协议,还有就是它不会像Socket类那样返回响应的开头信息。

构造方法
public URL(String spec);//填的是ip地址,格式如:http://ip地址:端口/资源地址,端口号可以省略

建立连接

public URLConnection openConnection();//它会抛出IOException异常,返回URLConnection对象

返回的URLConnection对象拿到服务器返回的结果,抛出IOException

public InputStream getInputStream();//读入返回的结果

把返回的结果写入,抛出IOException

public OutputStream getOutputStream();

 

服务器端

ServerSocket类

它是用来等待客户端发送请求的类,也就是等待请求网络传入。

方法:

构造函数

//port是端口号,你可以随意定义(在范围内0~65535,尽量使用4位以上的端口),抛出IOException异常,客户端通过该端口对服务器发送请求

public ServerSocket(int port);

等待

public Socket accept();//等待客户端连上服务器,抛出IOException异常

代码演示

1、客户端和服务器端的交互

服务器端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Server {
    public static void main(String[] args) {
        try {
            //设置服务器端口,建议使用4位的
            ServerSocket serversocket = new ServerSocket(5500);
            //创建线程池,但方便处理多线程,你也可以使用其他的线程池
            ThreadPoolExecutor service = new ThreadPoolExecutor(10, 11, 5000, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
            System.out.println("等待连接...");
            while(true){
                //等待客户端连接
                Socket socket=serversocket.accept();
                System.out.println("已连接...");
                //把相关io流放在线程内处理,可以避免线程多,从而引起的阻塞,submit就是提交任务,把任务交给线程池
                service.submit(()-> {
                    io(socket);
                });
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void io(Socket socket) {
        try {
            //获得客户端的数据
            InputStream in = socket.getInputStream();
            //服务器写入客户端数据
            OutputStream out = socket.getOutputStream();
            int len=0;
            byte[] bytes = new byte[1024 * 8];
            //把获得的数据在服务器端读出来
            while((len=in.read(bytes))!=-1){
                String s = new String(bytes,0,len,"utf-8");
                System.out.println("客户端说:"+s);
                //写入客户端 
                out.write(("服务器端回答:"+s).getBytes("utf-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
    public static void main(String[] args) {
        try {
            //设置客户端地址以及要访问的服务器所在端口,之前设置的那个服务器的端口是5500
            Socket socket = new Socket("localhost", 5500);
            //获得输出流,把客户端的说内容写入服务器
            OutputStream out = socket.getOutputStream();
            //因为要在客户端进行多次输入,这会造成io流的阻塞,因为线程是并行的,有可能会一起进去操作,这就造成了阻塞,因此需要线程进行处理
            new Thread(()->{
                Scanner sc = new Scanner(System.in);
                while(sc.hasNextLine()){
                    String next = sc.nextLine();
                    try {
                        //把客户端说的话写入服务器
                        out.write(next.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            //读取服务端的回答
            InputStream in = socket.getInputStream();
            int len=0;
            byte[] bytes = new byte[1024 * 8];
            //读入服务端写入的回答
            while((len=in.read(bytes))!=-1){
                String result = new String(bytes, 0, len, "utf-8");
                System.out.println(result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

结果

服务器端界面

等待连接...
已连接...
客户端说:晚上好
客户端说:早上好
客户端说:下午好

客户端界面

晚上好
服务器端回答:晚上好
早上好
服务器端回答:早上好
下午好
服务器端回答:下午好

2、从网上下载一张图片

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class DownLoad {
    public static void main(String[] args) {
        try {
            //用URL定位你要下载的图片,并且打开链接与这个图片的地址相连接
            HttpURLConnection connection=(HttpURLConnection) new URL("https://csdnimg.cn/pubfooter/images/csdn-kf.png").openConnection();
            //读取要获得的图片数据
            InputStream in = connection.getInputStream();
            int len=0;
            byte[] bytes = new byte[1024 * 8];
            //写入需要存放的地方
            FileOutputStream out = new FileOutputStream("E:\\photo.png");
            while((len=in.read(bytes))!=-1){
                out.write(bytes,0,len);
            }
            System.out.println("下载完毕");
            //关闭流和连接
            out.close();
            connection.disconnect();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果

下载完毕

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值