java之UDP与TCP

UDP

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

TCP

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

Socket

1.Socket就是为网络服务提供的一种机制
2.通信的两端都有Socket
3.网络通信其实就是Socket间的通信

4.数据在两个Socket间通过IO传输

UDP类

DatagramSocket:此类表示用于发送和接收数据报数据包的套接字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 /**
* 此代码演示UDP发送端
* */
public class UDPsend {

public static void main(String[] args)throws Exception
{

//定义一个UDP的Socket
DatagramSocket dS = new DatagramSocket() ;
String string = "udpDemo";
byte[] buf =string.getBytes();
int length = buf.length;
//获取本机IP
InetAddress address = InetAddress.getLocalHost();
//指定端口
int port= 7777;
//DatagramPacket该类表示数据报包。
DatagramPacket p = new DatagramPacket(buf, length, address, port);
//发送
dS.send(p);
//关闭
dS.close();
}

}

/**
* 此代码演示UDP接收端
* */
public class UDPrece {

public static void main(String[] args)throws Exception
{

DatagramSocket ds = new DatagramSocket(7777);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
byte[] data = dp.getData();
int length =dp.getLength();
String receiveddata= new String(data, 0, length);
System.out.println("Udp"+receiveddata);
ds.close();
}

}


TCP类

tcp分客户端和服务端
Socket:客户端对应的对象
ServerSocket:服务端对应的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*客户端
*在该对象建立时,就可以去连接指定主机。
*因为tcp是面向连接的,所以在建立socket服务时,
*就要有服务端的存在,并连接成功,形成通路后,在该通道进行数据的传输
*/
public static void main(String[] arg)
{
//创建客户端的Socket服务,指定目的主机和端口
Socket s = new Socket("192.168.1.254",10086);
//为了发送数据,应该获取socket流中的输出流
OutputStream out = s.getOutputStream();
out.write("TCPDemo".getBytes());
s.close();
}
/*
*服务端
*1.建立服务端的socket服务,ServerSocket,并监听一个端口
*2.获取连接过来的客户端对象
* 通过ServerSocket的 accept 方法。(阻塞式方法)
*3.客户端如果发过来数据,那么服务端要使用对应的客户端对象,
* 并获取到该对象的读取流来读取发过来的数据。并打印出来。
*4.(可选)关闭服务
*/
public static void main(String[] arg)
{
//建立服务端的socket服务并监听一个端口
ServerSocket ss = new ServerSocket(10003);
//通过accept方法获取连接过来的客户端对象
Socket s = ss.accept();

String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+":");
//使用客户端对象的读取流来读取数据
InputStream in = s.getInputStream();

byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String (buf,0,len));

//关闭客户端
s.close();
}


并发TCP

为了解决多客户端访问服务器的问题
于是需要使用多线程技术

1
2
3
4
5
6
7
8
9
10
11
12
Class TcpServer
{
public static void main(String[] srgs) throws Exception
{
ServerSocket ss = new ServerSocket(10000);
while(ture)//使用while(ture),每当新的客户端连接进来,就开启一个新线程
{
Socket s = ss.accept();
new Thread(new TcpThread(s)).start();
}

}


*举例:并发TCP上传图片

Class TcpThread implements Runnable
{
    private Socket s;
    TcpThread(Socket s)
    {
       this.s = s;
    }
    public void run()
    {
        String ip = s.getInetAddress().getHostAddress();
        try
        {
            int count = 1;
            System.out.println(ip+"...connecting");
            InputStream in = s.getInputStream();
            File file = new File(ip+"("+(count)+")"+".jpg");
            while(file.exists())
            {
               file = new File(ip+"("+(count++)+")"+".jpg");
            }

            FileOutputStream fos = new FileOutputStream("file");
            byte[] buf = new byte[1024];
            int len = 0;
            while((len=in.read(buf)) != -1)
            {
                fos.write(buf,0,len);
            }
            OutputStream out = s.getOutputStream();
            out.write("上传成功".getBytes());
            fos.close();
            s.close();
        }
        catch (Exception e)
        {
            throw new RuntimeException(ip+"上传失败");
        }
    }
}