Java实现UDP和TCP---聊天小程序

关于如何实现UDP和TCP连接(具体应用),下面给出了几个例子

UDP

客户端代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class UdpProducer {
	public static void main(String[] args) throws Exception {
		
		//建立套接字接口		
		@SuppressWarnings("resource")
		DatagramSocket socket = new DatagramSocket();
		InetAddress address = InetAddress.getByName("localhost");	
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  //实例化Scanner类	
		String line;
		while((line = br.readLine())!=null){
			//发送的数据报包
		    DatagramPacket datagramPacket = new DatagramPacket(line.getBytes(),line.getBytes().length,address,8080);
		    socket.send(datagramPacket);
		}
	}
}

客户端主动访问服务端,所以需要加上ip地址,这里访问本机使用localhost.

服务端代码

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class UdpConsumer {
	public static void main(String[] args) throws Exception {
		@SuppressWarnings("resource")
		DatagramSocket datagramSocket = new DatagramSocket(8080);//绑定消息接收端口8080
		// 用以存放接收数据的字节数组
	    byte[] msgByte = new byte[1024];  
	    // 接收消息的数据报包
	    DatagramPacket packet = new DatagramPacket(msgByte, msgByte.length);
		@SuppressWarnings({ "resource"})
		Scanner sc = new Scanner(System.in);  //实例化Scanner类		
	    while(true){
		    datagramSocket.receive(packet);
		    String msg = new String(packet.getData(),0,packet.getLength());
		    System.out.println("窗口B收到信息:"+msg);
	    }
	}
}

服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求,这里监听8080端口.

TCP

与UDP不同之处在于,TCP连接需要通过三次握手.

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 

这三次握手都不会携带任何待传送的数据.

客户端代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class TcpProducer {
	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("localhost",8010);
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
		OutputStream os = socket.getOutputStream();
		String line;
		while((line = br.readLine())!=null){
		    os.write( line.getBytes());
		    os.flush();
		}
	}
}

同样的,客户端需要主动访问服务端的ip'地址和端口号

服务端代码

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


public class TcpConsumer {
	public static void main(String[] args) throws Exception {
		@SuppressWarnings("resource")
		ServerSocket serverSocket = new ServerSocket(8010);//监听8010端口
        Socket accept = serverSocket.accept();//阻塞方法,等待发送端的链接请求
        while(true){
        	// 获取连接对象的输入流
            InputStream in = accept.getInputStream();
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            System.out.println(new String(buf,0,len));
        }

	}
}

UDP和TCP连接的不同点:

1.TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接.如上面的代码如果先启动UDP的客户端是不会报错的,而先启动TCP的客户端就会报错"connection refused"(连接被拒绝!);

2.TCP提供可靠的服务,更具准确性.相对而言UDP只管数据发送出去了,其它东西什么都不管.

3.UDP具有广播性,支持一对多发送;TCP是点对点协议;

4.UDP连接响应速度快,时效性更高,TCP连接需要经过多次握手;

下面是一个基于UDP连接的聊天小程序服务端代码;

窗口A与窗口B

public class WindowA {
	private static final int SEND_PORT = 8090;//向哪个端口发送信息
	private static final int RECEIVE_PORT = 8080;//绑定一个端口接收信息
	public static void main(String[] args) {
		System.out.println("开始聊天啦!");
		new Thread(new ReceiveListener(RECEIVE_PORT)).start();
		new Thread(new SendListener(SEND_PORT,"小红")).start();
	}
}




public class WindowB {
	private static final int SEND_PORT = 8080;//向哪个端口发送信息
	private static final int RECEIVE_PORT = 8090;//绑定一个端口接收信息
	public static void main(String[] args) {
		System.out.println("开始聊天啦!");
		new Thread(new ReceiveListener(RECEIVE_PORT)).start();
		new Thread(new SendListener(SEND_PORT,"小明")).start();
	}
}

接收监听:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Scanner;

public class ReceiveListener implements Runnable {

	private int port;
	
	ReceiveListener(int port){
		this.port = port;
	}
	
	@Override
	public void run() {
		try{
			@SuppressWarnings("resource")
			DatagramSocket datagramSocket = new DatagramSocket(port);//绑定消息接收端口8080
			// 用以存放接收数据的字节数组
		    byte[] msgByte = new byte[1024];  
		    // 接收消息的数据报包
		    DatagramPacket packet = new DatagramPacket(msgByte, msgByte.length);	
		    while(true){
			    datagramSocket.receive(packet);
			    String msg = new String(packet.getData(),0,packet.getLength());
			    System.out.println(msg);
		    }
		}catch(Exception e){
			System.out.println("出错了!出错信息:"+e.getMessage());
		}
	}

}

发送监听:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SendListener implements Runnable {
	private int port;
	private String name;
	private static SimpleDateFormat format;
	{
		format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	}
	
	SendListener(int port,String name){
		this.port = port;
		this.name = name;
	}
	
	@Override
	public void run() {
		try{
			@SuppressWarnings("resource")
			DatagramSocket socket = new DatagramSocket();
			InetAddress address = InetAddress.getByName("localhost");	
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));  //实例化Scanner类	
			String line;
			while((line = br.readLine())!=null){
				//发送的数据报包
				line = name +":"+line+" "+format.format(new Date());
			    DatagramPacket datagramPacket = new DatagramPacket(line.getBytes(),line.getBytes().length,address,port);
			    socket.send(datagramPacket);
			}
		}catch(Exception e){
			System.out.println("出错了!出错信息:"+e.getMessage());
		}
	}
	
}

运行结果:

窗口B:

窗口A:

就是这样的!喵~如果你想知道更多关于TCP和UDP的知识,请点击这里Http和Socket 优劣比较

好了!掰掰!

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值