Socket编程实现TCP、UDP样例

一.Socket简介

socket套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元.

换句话说socket(套接字)的作用就是将应用程序通过端口连接起来.

在Java中,提供了一些基础类供我们去进行一些网络传输的操作.

二.Socket实现TCP

TCP通信简介

TCP通信能实现两台计算机之间的数据交互,通信的两端要严格区分客户端和服务器端

  1. 服务端程序,需要事先启动,等待客户端的连接.
  2. 客户端程序应该主动连接服务器端,连接成功才能通信.服务端不可以主动连接客户端.

所谓的TCP协议不过是传输数据时有固定的文本格式而已,底层传输数据是一样的.

使用对象及方法简介

在JAVA中,提供了两个类用于实现TCP通信程序.

  1. 客户端:java,net.Socket类表示.创建Socket(套接字)对象,向服务端发出连接请求,服务器端响应请求,两者建立连接开始通信.
  2. 服务端:java.net.ServerSocket类表示,创建ServerSocket对象,相等于开启了一个服务,并等待客户端的连接.

1.Socket类

  1. 构造方法:
    public Socket(String host,int port):
    创建套接字对象并将其连接到指定的主机上的指定端口号.(如果指定的host是null,则相当于指定地址为回送地址).
    host:IP地址 port:端口号

  2. 其他主要方法.
    (1).public InputStream getInputStream():获取套接字的输入流.
        接收数据.返回InputStream对象

    (2).public OutPutStream getOutPutStream();获取套接字的输出流.
        发送数据.返回OutputStream对象

    (3).public void close():关闭此套接字.

    (4).public void shutdownOutPut():禁用此套接字的输出流.

2.ServerSocket类
实现了服务器套接字,该对象等待网络请求.

  1. 构造方法:
    public ServerSocket(int port):
    创建ServerSocket对象,并将其绑定到一个指定的端口号上.
  2. 其他主要方法:
    public Socket accept():
    侦听并接受连接,返回一个新的Socketd对象.该方法会一直运行直到建立连接.

代码实现

服务端代码
public class Server {
    public static void main(String[] args) {
        //1.构建服务器对象
        ServerSocket serverSocket=null;
        BufferedReader br=null;
        PrintWriter printWriter=null;
        try {
             serverSocket=new ServerSocket(6789);   //注意端口号不要比1024小

             //2.设置准备阶段,一直等待接收信息
            Socket socket = serverSocket.accept();         //这里返回客户端的对象,在客户端关闭,这里不进行关闭
            //5.获得套接字之后(连接),客户端读取数据
            //写法一:
//            InputStream input = socket.getInputStream();
//            InputStreamReader inputReal=new InputStreamReader(input);
//            BufferedReader br=new BufferedReader(inputReal);                //BufferedRead有读取一行的方法,比较方便
            //写法二.(升级版)
            br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String temp=null;

            printWriter= new PrintWriter(socket.getOutputStream());
            while((temp=br.readLine())!=null){
                System.out.println(temp);
                //6.客户端发送相应数据,一定得写在读数据的里面,不然不会执行这些语句
                printWriter.println("服务器端相应数据");
                printWriter.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(printWriter!=null){
                printWriter.close();
            }
            if(br!=null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
            if(serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}
客户端代码
public class Client {
    public static void main(String[] args) {
        //3建立Socket对象
        Socket socket=null;
//        OutputStreamWriter outreal=null;
        PrintWriter pw=null;
        BufferedReader bufferedReader=null;
        try {
            socket=new Socket("127.0.0.1",6789);
            //4.建立输出流,客户端主动向服务端发出信息.
            //方式一:
//            OutputStream out = socket.getOutputStream();
//            outreal=new OutputStreamWriter(out);
//            outreal.write("我发出请求,请求连接");
//            outreal.write("\r\n".toCharArray());
//
//            outreal.write("我发出请求,请求连接");
//            outreal.write("\r\n".toCharArray());
//            outreal.flush();                            //必须刷新
            //方式二:(该方法更简便一点,使用PrintWriter)
            OutputStream out = socket.getOutputStream();
            pw=new PrintWriter(out);
            pw.println("客户端发出请求,请求连接");
            pw.flush();
            pw.println("客户端发出请求,请求连接");
            pw.flush();
            //7.接受服务器端相应数据
            bufferedReader= new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String temp=null;
            while((temp=bufferedReader.readLine())!=null){
                System.out.println(temp);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(bufferedReader!=null){                 //防止出现空指针异常
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(pw!=null){
                pw.close();
            }
            if(socket!=null){                        
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

    }
}

上述代码其实主要分为7个步骤:

  1. 构建服务器对象
  2. 服务端开启等待
  3. 构造客户端对象
  4. 客户端主动发送数据
  5. 服务端接收数据
  6. 服务端发送相应数据
  7. 客户端接收相应数据

最主要的就是服务端要先开启等待监听,然后客户端去和服务端建立连接,然后就可以发送数据了.

三.Socket实现UDP

UDP通信简介

  1. UDP协议.
    用户数据报协议(UDP) 是网络信息传输的另- -种形式。基于UDP的通信和基于TCP的通信不
    同,基于UDP的信息传递更快,但不提供可靠的保证。使用UDP传递数据时,用户无法知道数据能 否正确地到达主机,也不能确定到达目的地的顺序是否和发送的顺序相同。虽然UDP是–种不可靠 协议,但如果需要较快地传输信息,并能容忍小的错误,可以考虑使用UDP.

  2. 基于UDP通信的基本模式.
    (1)将数据打包(称为数据包),然后将数据包发往目的地。
    (2)接收别人发来的数据包, 然后查看数据包。

UDP程序的使用步骤

发送数据包:

  1. 使用DatagramSocket(创建一个数据包套接字).
  2. 使用DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)创建要发送的
    数据包。
  3. 使用DatagramSocket类的send()方法发送数据包。

接收数据包:

  1. 使用DatagramSocket(int port)创建数据包套接字,绑定到指定的端口。
  2. 使用DatagramPacket(byte[] buf, int length)创建字节数组来接收数据包。
  3. 使用DatagramSocket类的receive()方法接收UDP包。

注意:
    DatagramSocket类的receive()方法接收数据时,如果还没有可以接收的数据,在正常情况下
receive()方法将一直阻塞,直到网络上有数据传来.此时receive()方 法接收该数据并返回。
    如果网络上没有数据发送过来,receive(方法也没有阻塞,肯定是程序有问题,大多数是使用了一个被其他程序占用的端口号。

代码实现

服务端代码
 public class UDPServer {
	public static void receive(int port) {
		try {
			//1.创建套接字,绑定端口
			DatagramSocket socket = new DatagramSocket(port);
			//2.创建DatagramPacket对象用于接收数据
			byte[] buf=new byte[1024];
			DatagramPacket datagramPacket = new DatagramPacket(buf,buf.length);
			//接收数据
			System.out.println("服务端初始化成功...");
			while(true) {
				socket.receive(datagramPacket);
				System.out.println(new String(buf));
			}
			
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
			receive(10111);			
		
	}
}
客户端代码
  public class UDPClient {
	public static void sendData(String ip,String data,int port) {
		DatagramSocket datagramSocket;
		try {
			//1.创建套接字
			datagramSocket = new DatagramSocket();
			//2.创建要发送的数据包
			InetAddress address = InetAddress.getByName(ip);
			DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), data.length(), address, port);
			//3.发送数据
			datagramSocket.send(datagramPacket);
			System.out.println("客户端发送数据成功...");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		sendData("192.168.77.15", "你是个大傻子",10111);
	}
}


今天的分享就到这里了,有问题可以在评论区留言,均会及时回复呀.
我是bling,未来不会太差,只要我们不要太懒就行, 咱们下期见.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员bling

义父,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值