首页 > 代码库 > 网络编程

网络编程


1、InetAddress InetSocketAddress
2、URL
3、TCP:ServerSocket Socket
4、UDP:DatagramSocket DatagramPacket


1、InetAddress:封装计算机的ip地址和dns,没有端口
方法:
getHostAddress() 返回ip地址
getHostName() 返回域名|本机为计算机名
InetAddress.getLocalHost();
InetAddress.getByName("ip地址|域名");
2、InetSocketAddress:封装端口
1)、创建对象: 
InetSocketAddress(String hostname, int port) 
InetSocketAddress(InetAddress addr, int port) 
2)、方法:
getAddress()//返回IP 
getHostName() //返回hostname
getPort() //返回端口
3、URI:统一资源标识符,用来标识唯一资源
URL:统一资源定位器,是一种具体的URI
4部分组成:协议、存放资源的主机域名、端口、资源文件名
一、创建
URL(String spec)  :绝对路径构建
URL url = new URL(" http://www.baidu.com:80/index.html#aa?username=bjsxt");
URL(URL context, String spec)  :相对路径构建
url = new URL("http://www.baidu.com:80/a/");
url = new URL(url, "b.txt");//相对路径
System.out.println(url.toString());
输出:http://www.baidu.com:80/a/b.txt
二、方法
System.out.println("协议:"+url.getProtocol());
System.out.println("域名:"+url.getHost());
System.out.println("端口:"+url.getPort());
System.out.println("资源:"+url.getFile());
System.out.println("相对路径:"+url.getPath());
System.out.println("锚点:"+url.getRef()); //锚点
System.out.println("参数:"+url.getQuery());//?参数 :存在锚点  返回null ,不存在,返回正确
三、流
openStream();//返回inputstream
UDP:以数据为中心,非面向连接,不安全,数据可能丢失,效率高(面向数据)
类:DataGramSocket DatagramPacket
1、客户端
1)、创建DatagramSocket +指定端口
2)、准备数据 字节数组
3)、打包 DatagramPacket + 服务器地址 及端口
4)、发送
5)、释放资源
//创建服务器端+端口
DatagramSocket server = new DatagramSocket(8888);
//准备接受容器
byte[] container = new byte[1024];
//封装成包 datagramPacket(byte[] buf,ing length)
DatagramPacket packet = new DatagramPacket(container,container.length);
//接受数据
server.receive(packet);
//分析数据
byte[] data = http://www.mamicode.com/packet.getData();
int len = packet.getLength();
System.out.println(new String(data,0,len));
//释放资源
server.close();


2、服务器端:
1)、创建服务端 datagramSocket 类 +指定端口
2)、准备接受容器 字节数组 DatagramPacket
3)、包接受数据
4)、分析
5)、释放资源
//创建客户端+端口
DatagramSocket client = new DatagramSocket(6666);
//准备数据
String msg = "udp编程";
byte[] data = http://www.mamicode.com/msg.getBytes();
//打包(发送的地点及端口)
DatagramPacket packet = new DatagramPacket(data, data.length, new InetSocketAddress("localhost",8888));
//发送’
client.send(packet);
//释放资源
client.close();


byte[] data = http://www.mamicode.com/null;
DataArrayOutputStream


传递数据和类型
使用dataInputStream/dataoutputstream
/*
* 字节数据+data 输入流
*/
public static double convert(byte[] data) throws IOException{
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
double num = dis.readDouble();
return num;
}
/*
* double转字节数组
*/
public byte[] convert(double data) throws IOException{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(bos);
dos.writeDouble(data);
dos.flush();
dos.close();
byte[] byteArray = bos.toByteArray();
return byteArray;
}

Socket通信
基于tcp,面向连接,安全可靠,效率低,类似于打电话

一、面向连接:请求-响应,request-response
二、socket编程
1、服务器端serverSocket
//创建服务器,指定端口
ServerSocket server = new ServerSocket(8888);
//接受客户端连接 注射室
Socket socket = server.accept();
System.out.println("一个客户端建立连接");
//发送数据+接受数据
String msg = "欢迎使用";
/*BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write(msg);
bw.newLine();
bw.flush();*/
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(msg);
dos.flush();
2、客户端Socket
//创建客户端 不许指定服务器端+端口
Socket client = new Socket("localhost", 8888);
//接受数据+发送数据
/*BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String echo = br.readLine();//阻塞式方法*/
DataInputStream dis = new DataInputStream(client.getInputStream());
String echo = dis.readUTF();
System.out.println(echo);

聊天室:

package socket;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    private List<MyChannel> all = new ArrayList<MyChannel>();
    public static void main(String[] args) throws IOException {
        new Demo().start();
    } 
    
    public void start() throws IOException{
        //创建服务器,指定端口
        ServerSocket server = new ServerSocket(8888);
        while(true){
            Socket socket = server.accept();
            MyChannel channel = new MyChannel(socket);
            all.add(channel);//加入容器统一管理
            new Thread(channel).start();//一条道路
        }
    }
    /*
     * 一个客户端一条道路
     */
    class MyChannel implements Runnable {
        private DataInputStream dis;
        private DataOutputStream dos;
        private boolean isRunning = true;
        private String name;
        public MyChannel(Socket client) {
            try {
                //输入流,接受数据
                dis = new DataInputStream(client.getInputStream());
                //输出流,发送数据
                dos = new DataOutputStream(client.getOutputStream());
                this.name = dis.readUTF();
                this.send("欢迎进入聊天室");
                sendOthers(this.name +"进入了聊天室",true);
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dis,dos);
            }
        }
        /*
         * 读取数据
         */
        private String receive(){
            String msg = "";
            try {
                msg = dis.readUTF();
                System.out.println("服务器接收到客户端数据"+msg);
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dis);
                all.remove(this);//移除自身
            }
            return msg;
        }
        /*
         *发送数据
         */
        public void send(String msg){
            System.out.println("服务器向其他客户端转发消息"+msg);
            if(null == msg || msg.equals("")){
                return;
            }
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                isRunning = false;
                CloseUtil.closeAll(dos);
                all.remove(this);//移除自身
            }
        }
        /*
         * 发送给其他客户端
         */
        private void sendOthers(String msg,boolean sys){
            //是否为私聊,以@开头标识私聊
            if(msg.startsWith("@") && msg.indexOf(":") > -1){//私聊
                //获取name
                String name = msg.substring(1,msg.indexOf(":"));
                String content = msg.substring(msg.indexOf(":")+1);//indexOf左闭右开
                for(MyChannel other:all){
                    if(other.name.equals(name)){
                        other.send(this.name + "对你说"+content);
                    }
                }
            }else{
                for(MyChannel other:all){
                    if(other == this){
                        //如果是自己不发送
                        continue;
                    }
                    if(sys){//系统信息
                        other.send("系统消息:"+msg);
                    } else{
                        //发送给其他客户端
                        other.send(this.name +"对所人说:"+msg);
                    }
                }
            }
            
        }
        @Override
        public void run() {
            while(isRunning){
                sendOthers(receive(),false);
            }
        }
    }
}
package socket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class DemoClient {
    public static void main(String[] args) throws IOException {
        System.out.println("请输入名称");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String name = br.readLine();
        if(name.equals("")){
            return;
        }
        //创建客户端  不许指定服务器端+端口
        Socket client = new Socket("localhost", 8888);
        new Thread(new Send(client,name)).start();
        new Thread(new Receive(client)).start();
        
    }
    
}

/*
 * 发送数据
 */
class Send implements Runnable{
    //控制台输入流
    private BufferedReader console;
    //管道输出流
    private DataOutputStream dos ;
    //名称
    private String name ;
    //判断
    private boolean inRunning = true;
    public Send() {
        console = new BufferedReader(new InputStreamReader(System.in));
    }
    public Send(Socket client,String name){
        this();
        try {
            dos = new DataOutputStream(client.getOutputStream());
            this.name = name;
            send(this.name);
        } catch (IOException e) {
            inRunning = false;
            CloseUtil.closeAll(dos,console);
        }
    }
    //从控制台接受数据
    private String getMsgFrommConsole(){
        try {
            return console.readLine();
        } catch (IOException e) {
//            e.printStackTrace();
            inRunning = false;
            CloseUtil.closeAll(dos,console);
        }
        return "";
    }
    //发送数据
    public void send(String msg){
        if(null != msg && !msg.equals("")){
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                //e.printStackTrace();
                inRunning = false;
                CloseUtil.closeAll(dos,console);
            }
        }
    }
    @Override
    public void run() {
        while(inRunning){
            send(getMsgFrommConsole());
        }
    }
}
/*
 * 接受数据
 */
class Receive implements Runnable{
    private DataInputStream dis ;
    private boolean isRunning = true;
    public Receive() {
        
    }
    public Receive(Socket client) {
        try {
            dis = new DataInputStream(client.getInputStream());
        } catch (IOException e) {
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
    }
    /*
     * 接受数据
     */
    public String receive(){
        String msg = "";
        try {
            msg = dis.readUTF();
        } catch (IOException e) {
            isRunning = false;
            CloseUtil.closeAll(dis);
        }
        return msg;
    }
    @Override
    public void run() {
        while(isRunning){
            System.out.println(receive());
        }
    }
    
}
package socket;

import java.io.Closeable;

/*
 * 关闭流
 */
public class CloseUtil {
    public static void closeAll(Closeable... io){//可变参数
        for(Closeable temp:io){
            try{
                if(null != temp){
                    temp.close();
                }
            }catch(Exception e){
                
            }
        }
        
    }
}

 

网络编程