黑马程序员-12 网络编程

传输协议
UDP
将数据及源和目的封装到数据包中,不需要建立连接;
每个数据包的大小限制在64K以内;
因无连接,是不可靠协议;
不需要建立连接,速度快。
TCP
建立连接,形成传输数据的通道;
在连接中进行大量数据传输;
通过三次握手完成连接,是可靠协议;
必须建立连接,效率稍低。

InetAddress 表示互联网协议 (IP) 地址
static InetAddress getLocalHost() ;//返回本地主机


Socket
Socket就是为网络服务提供的一种机制;
通信的两端都有Socket;
网络通信其实就是Socket间的通信;
数据在两个Socket间通过IO传输。

UDP传输
DatagramSocket和DatagramPacket

发送例

import java.net.*;
class  UdpSend
{
	public static void main(String[] args) throws Exception
	{
		//1,创建udp服务。通过DatagramSocket对象。
		DatagramSocket ds = new DatagramSocket();

		//2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port) 

		byte[] buf = "udp ge men lai le ".getBytes();
		DatagramPacket dp = 
			new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.102"),10000);

		//3,通过socket服务,将已有的数据包发送出去。通过send方法。
		ds.send(dp);

		//4,关闭资源。

		ds.close();
	}
}

接受例

import java.net.*;
class  UdpRece
{
    public static void main(String[] args) throws Exception
    {
        //1,创建udp socket,建立端点。
        DatagramSocket ds = new DatagramSocket(10000);
        while(true)
        {
        //2,定义数据包。用于存储数据。
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);

        //3,通过服务的receive方法将收到数据存入数据包中。
        ds.receive(dp);//阻塞式方法。
        

        //4,通过数据包的方法获取其中的数据。
        String ip = dp.getAddress().getHostAddress();

        String data = new String(dp.getData(),0,dp.getLength());

        int port = dp.getPort();

        System.out.println(ip+"::"+data+"::"+port);

        }
        //5,关闭资源
        //ds.close();

    }
}

 

===========================================================
线程应用模拟聊天程序

import java.io.*;
import java.net.*;

public class ChatDemo {
    public static void main(String[] args) throws Exception{
        DatagramSocket sendSocket = new DatagramSocket();
        DatagramSocket receSocket = new DatagramSocket(10002);

        new Thread(new Send(sendSocket)).start();
        new Thread(new Rece(receSocket)).start();

    }

}

class Send implements Runnable{
    private DatagramSocket ds;
    public Send(DatagramSocket ds)
    {
        this.ds = ds;
    }
    @Override
    public void run() {
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        try {
            while((line = bufr.readLine())!= null){
                byte[] buf = line.getBytes();
                DatagramPacket dp = 
                        new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.102"),10002);
                ds.send(dp);
                if(line.equals("over")) {
                    bufr.close();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }    
}

class Rece implements Runnable{
    private DatagramSocket ds;
    public Rece(DatagramSocket ds)
    {
        this.ds = ds;
    }
    @Override
    public void run() {
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        while(true)
        try {
            ds.receive(dp);
            String ip = dp.getAddress().getHostAddress();
            String data = new String(dp.getData(),0,dp.getLength());
            if(data.equals("over")) {
                System.out.println("ip-"+ip+"离开了");
                break;
            }
            System.out.println("ip-"+ip+"say:"+data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

==============================================
Tcp传输。

1,tcp分客户端和服务端。
2,客户端对应的对象是Socket。服务端对应的对象是ServerSocket。

客户端,
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
因为tcp是面向连接的。所以在建立socket服务时,
就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。

服务端:
1,建立服务端的socket服务。ServerSocket();
并监听一个端口。
2,获取连接过来的客户端对象。
通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。
并打印在控制台。
4,关闭服务端。(可选)


示例
演示tcp的传输的客户端和服务端的互访。
需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。

import java.io.*;
import java.net.*;

class TcpClient2 
{
    public static void main(String[] args)throws Exception 
    {
        Socket s = new Socket("192.168.1.254",10004); //指定要连接主机和端口
        
        OutputStream out = s.getOutputStream(); //为了发送数据,应该获取socket流中的输出流。

        out.write("服务端,你好".getBytes());

        
        InputStream in = s.getInputStream();

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        System.out.println(new String(buf,0,len));

        s.close();
    }
}


class TcpServer2
{
    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(10004); //建立服务端socket服务。并监听一个端口。

        Socket s = ss.accept(); //通过accept方法获取连接过来的客户端对象。

        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+"....connected");
        InputStream in = s.getInputStream(); //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        System.out.println(new String(buf,0,len));


        OutputStream out = s.getOutputStream();


        Thread.sleep(10000);
        out.write("哥们收到,你也好".getBytes());

        s.close();

        ss.close();
    }
}

 

==================

posted @ 2012-10-28 16:29  EnderViking  阅读(168)  评论(0)    收藏  举报