网路编程(二)UDP和TCP协议下传输数据

来源:互联网 发布:gps测绘仪器价格 知乎 编辑:程序博客网 时间:2024/05/16 09:10

UDP传输数据特点
只需要一个目的地,然后将数据一直发送就行了。类似发快递

1.将数据及源和目的封装成数据包中,不需要建立连接2.每个数据报的大小在限制在64k内3.因无连接,是不可靠协议4.不需要建立连接,速度快(DatagramSocket 和 DatagramPacket类 )

TCP传输数据特点
3次握手确认后才可以传输,类似通话

1.建立连接,形成传输数据的通道。2.在连接中进行大数据量传输3.通过三次握手完成连接,是可靠协议4.必须建立连接,效率会稍低(Socket 和 ServerSocket类)

☆TCP传输最容易出现的问题

客户端连接上服务端,两端都在等待,没有任何数据传输。
通过例程分析:
因为read方法或者readLine方法是阻塞式。
解决办法:
自定义结束标记
使用shutdownInput,shutdownOutput方法。

实例 代码实现
UDP 从一个本机的一个端口发送信息(达哥,你可以的)到另一个端口
发送类

package cn.hncu.dage.UDP;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> * @version 2017-4-5  下午7:27:28 * @fileName SendDemo.java */public class SendDemo {    public static void main(String[] args) {        try {            DatagramSocket ds =null;            //1.创建一个用来发送数据包的Socket (10000表示发送的端口号)            // 这里是封装你要发送的信息                ds = new DatagramSocket();                String str = "达哥,你可以的";                byte buf [] = str.getBytes();                 //2.用一个数据包发发送数据,buf数据小于64K,然后要给发送的IP(机器号)以及接受软件的端口号(10001)                DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("113.242.132.34"), 10001);                //3.调用一个方法发送                ds.send(dp);            // 4.关流            ds.close();        } catch (IOException e) {            e.printStackTrace();        }    }}

接收类

package cn.hncu.dage.UDP;import java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> * @version 2017-4-5  下午8:23:57 * @fileName ReceiveDemo.java */public class ReceiveDemo {    public static void main(String[] args) {        try {            // 1.创建一个接收数据的Socket 接收的端口号要与前面发送数据包的端口号一致,不然别找不到            DatagramSocket ds = new DatagramSocket(10001);            //2. 要创建一个数据包来接? 为什么呢?            /**             * 在网络中传输的是字节和字符,不是前面的数据包了,所以就需要新的数据包把数据收起来             */            byte buf [] = new byte [1024];            DatagramPacket dp = new DatagramPacket(buf, buf.length);            //3.一个接收方法            ds.receive(dp);            //4.把接收的数据解析出来            /**法律意识             * 一定要追踪数据的来源地址,万一别人给你发反动信息呢?              * 网警抓了,你有来源地址就没事。             */            // 来源IP和来源端口号            String ip = dp.getAddress().getHostAddress();            int port = dp.getPort();            String info = new String(dp.getData(),0,dp.getLength());            System.out.println("Ip地址为"+ip+"发来消息如下");            System.out.println(info);        } catch (IOException e) {            e.printStackTrace();        }    }}

结果这里写图片描述

TCP 客户端发送消息到服务器,服务器发消息给客户端。就是通信
服务器代码

package cn.hncu.dage.TCP;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> * @version 2017-4-5  下午8:52:16 * @fileName MySocketSever.java */public class MySocketSever {    public static void main(String[] args) {        // 1. 写个SeverSocket 指定端口 等待握手        try {            ServerSocket server = new ServerSocket(8888);        while (true) {            //2.握手通过一个accept() 方法可以得到发送 请求的线程            Socket s = server.accept();            // 读取客户端发来的信息            InputStream in = s.getInputStream();            byte bs[] = new byte[1024];            in.read(bs);            String  ip = s.getInetAddress().getHostAddress();            System.out.println("客户端Ip为"+ip+"发来"+new String(bs));            // 向客户端发送消息            OutputStream out = s.getOutputStream();            DataOutputStream dout = new DataOutputStream(out);            dout.writeUTF("达哥,你是最棒的!!!");            dout.close();        }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

客户端代码

package cn.hncu.dage.TCP;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;/** * @author<a href="mailto:953801304@qq.com">胡龙华</a> * @version 2017-4-5  下午9:01:50 * @fileName MySocketClient.java */public class MySocketClient {    public static void main(String[] args) {        try {            Socket s = new Socket("113.242.132.34", 8888);            // 当能向下执行的时候说明请求成功了,否则请求失败就异常了            // 发送给服务器: 消息            OutputStream out =s.getOutputStream();            DataOutputStream dout = new DataOutputStream(out);            String str = "Yes,I can";            dout.writeUTF(str);            //接收来自服务器的消息            InputStream in = s.getInputStream();            DataInputStream din = new DataInputStream(in);            String str2 = din.readUTF();            System.out.println("服务器说:"+str2);            dout.close();            din.close();        } catch (UnknownHostException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

结果
这里写图片描述
这里写图片描述

下面再用两个端口,一个模拟客户端,一个模拟服务器,向服务器上传一个小文件
服务器代码并启动

package cn.hncu.dage.TCP.FilePass;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.FileWriter;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;public class UploadTextServer {    public static void main(String[] args) throws IOException {        //1创建ServerSocket        ServerSocket s = new ServerSocket(7777);        //2获得握手方(客户端)对应的socket        Socket sk = s.accept();        //3读取客户端上传的文件数据----源:socket, 目的:本地磁盘        InputStream in = sk.getInputStream();        BufferedReader br = new BufferedReader(new InputStreamReader(in));        PrintWriter pw = new PrintWriter(new FileWriter("c.txt"),true);        String str = null;        while( (str=br.readLine())!=null){            System.out.println("Server "+str);            pw.println(str);                 }        DataOutputStream dout = new DataOutputStream(sk.getOutputStream());        dout.writeUTF("文件上传成功");        sk.close();        s.close();    }}

客户端代码

package cn.hncu.dage.TCP.FilePass;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;public class UploadTextClient {    public static void main(String[] args) throws IOException {        Socket s = new Socket("113.242.142.12", 7777);        BufferedReader br = new BufferedReader(new FileReader("a.txt"));        PrintWriter pw = new PrintWriter(s.getOutputStream(),true);        String str = null;        while( (str=br.readLine())!=null){        //  pw.write(str);        //  pw.flush(); // 刷缓存啊!!!            pw.println(str);        }        //★给服务器发送一个结束标记        s.shutdownOutput();        // 接收服务器消息        //接收服务器的应答消息        BufferedReader br2 = new BufferedReader( new InputStreamReader(s.getInputStream()) );        String info = br2.readLine();        System.out.println("server:"+info);        s.close();    }}

开始只有a.txt 文件
这里写图片描述
然后 上传来了c.txt文件
这里写图片描述
对比两个文件
这里写图片描述
是完全相同的,当然,这里并不严谨没有考虑中文乱码问题。

0 0
原创粉丝点击