Sockey编程之基于 UDP 协议的 Socket 编程

一、基于 UDP 协议的 Socket 编程

1.端口选择

已知端口:0~1023,为固定服务保留。

已注册的端口:1024~49151,供普通用户的普通用户进程或程序使用。  

动态或私用端口: 49152~65535,没有注册服务。

2.原理

a.基于UDP的套接字就是数据报套接字(ava.net.DatagramSocketj)。

b.两个都要先构造好相应的数据包(java.net.DatagramPacket)。

c.在DatagramPacket包中的函数 intgetLength()返回实际接受的字节数,byte[]getData()返回接受到的数据。

d.要想接受端给发送端回信息,就需要知道发送端的IP地址InetAddress getAddress()和发送端进程所绑定的端口号int getPort()。

e.数据报套接字发送成功之后,就相当于建立了一个虚连接,双方可以发送数据。

 3.编写代码(用Java的Swing技术)

(1)首先,建立通信界面的可视化视图,用Java的JFrame窗口建立;用init()函数初始化这个页面; 

public static void init() {
		JFrame frame = new JFrame("UDPServer");   //初始化一个frame窗口
		frame.setBounds(100, 100, 700,500 );     //setBounds(int left, int top, int right, int bottom)
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     //设置退出方法
		frame.getContentPane().setLayout(null);
		
		JLabel lblip = new JLabel("对方IP:");
		lblip.setBounds(47, 39, 72, 18);
		frame.getContentPane().add(lblip);
		
		JLabel lblip_1 = new JLabel("用户名:");
		lblip_1.setBounds(47, 89, 72, 18);
		frame.getContentPane().add(lblip_1);
		
		JLabel lblip_2 = new JLabel("对方端口:");
		lblip_2.setBounds(320, 39, 80, 18);
		frame.getContentPane().add(lblip_2);
		
		JLabel label = new JLabel("本机端口:");
		label.setBounds(320, 89, 80, 18);
		frame.getContentPane().add(label);
		
		JTextField textField = new JTextField("127.0.0.1");
		textField.setBounds(100, 36, 150, 27);
		frame.getContentPane().add(textField);
		
		JTextField textField_1 = new JTextField("徐武莉",10); 
		textField_1.setEditable(false);
		textField_1.setBounds(100, 86, 150, 27);
		frame.getContentPane().add(textField_1);
		
		JTextField textField_2 = new JTextField("6000",10);
		textField_2.setBounds(390, 36, 100, 27);
		frame.getContentPane().add(textField_2);
		
		JTextField textField_3 = new JTextField("9000",10);
		textField_3.setBounds(390, 86, 100, 27);
		frame.getContentPane().add(textField_3);
		
		textArea= new JTextArea(10,15);
		textArea.setBounds(47, 133, 600, 191);
		textArea.setLineWrap(true);
		JScrollPane jsp = new JScrollPane(textArea);//给文本区添加滚动条
		frame.getContentPane().add(textArea);
		
		JTextField text_send = new JTextField();
		text_send.setBounds(47, 346, 450, 31);
		frame.getContentPane().add(text_send);
		text_send.setColumns(10);
		
		JButton button = new JButton("发送");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String message=textField_1.getText()+":"+text_send.getText()+"\n";
				int port=Integer.parseInt(textField_2.getText());
				textArea.append(message);	
				System.out.println("发送信息为:"+message+"对方端口号:"+port);
				UDPSend usend=new UDPSend(message,port);
				usend.send();
			}
		});
		button.setBounds(520, 346, 113, 31);
		frame.getContentPane().add(button);
		frame.setVisible(true);
	}

(2)新建一个UDPSend()的程序进行发送数据;

在这个程序中,用DatagramPacket类表示数据报包。数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。 

dp = new DatagramPacket(mesg.getBytes(), mesg.getBytes().length, 
        			InetAddress.getByName("localhost"),port);  

对数据报的数据进行赋值,mesg.getBytes()表示消息的字节数,mesg.getBytes().length表示消息字节数的长度,调用InetAddress类的getByName()方法去获得本地服务器的IP号InetAddress.getByName("localhost"),port为要发送的端口号;

DatagramSocket() 类用来构造数据报套接字并将其绑定到本地主机上任何可用的端口。    ds.send(dp)为调用DatagramSocket() 类的send()方法发送数据包;

(3)发送按键的按钮监听,当按“发送”时,获取发送的数据,并且调用UDPSend类进行数据的发送;

3.button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				String message=textField_1.getText()+":"+text_send.getText()+"\n";
				int port=Integer.parseInt(textField_2.getText());
				textArea.append(message);	
				System.out.println("发送信息为:"+message+"对方端口号:"+port);
				UDPSend usend=new UDPSend(message,port);
				usend.send();
			}
		});

addActionListener(new ActionListener)用内置函数去对监听按钮事件当点击发送时.getText()函数去获取文本框的数据;并且调用函数进行数据传递和send的发送

(4)在Main()函数里面ds=new DatagramSocket(9000)去绑定端口号,

 byte[] buf = new byte[1024],去对数据new一个字节为1024的数组大小

  dp=new DatagramPacket(buf,buf.length)去对数据包进行初始化

(5)接收数据

 while(true){
			  try {
				ds.receive(dp);
				String info=new String(buf,0,dp.getLength());   
			    textArea.append(info);				
			} catch (IOException e) {
				e.printStackTrace();
			}

while(true)一直去监听发送过来的数据ds.receive(dp)去接收数据包的数据并且将数据转换为string的类型数据将内容显示在textArea的输入框中

4.界面示意

(1)基于UDP的socket点对点通信

a.两个客户端进行点对点通信,都是在本地服务器上进行通信,因此地址都是127.0.0.1;初始化两方的端口分别为6000和9000;

                             

b.向对方发送信息,两方都显示发送的信息结果,说明信息发送成功

                            

c.回复对方信息,由以下信息可以看出,双方可以进行正常的通信,成功实现了点对点通信的功能;

                              

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值