UDP协议聊天程序

问题:按照毕老师视频中讲的程序写了一遍,为什么程序输入over停不下来?如何把这个聊天程序做成界面化的

package UDPChat;
//毕老师UDP聊天程序问题
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
public class UDPChatTest1 {
/*
* UDP协议的聊天程序:收和发是分开的,所以将收发的动作分别封装到两个线程的run方法中即可 1.定义两个类send
* rece分别实现Runnable,初始化时关联DatagramSocket 2.将收发动作分别封装到两个类的run方法中
* 3.在主函数中开启两个线程
*/
private Frame f;
private TextArea ta1, ta2;
private Button b;


UDPChatTest1() {
method_0();
}


private void method_0() {
Frame f = new Frame("对话");
TextArea ta1 = new TextArea();
TextArea ta2 = new TextArea();
Button b = new Button("发送");

f.setBounds(200, 100, 400, 350);
f.add(ta1);
f.add(ta2);
f.add(b);
myEvent();
f.setVisible(true);

}

private void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("操作了窗体上的关闭");
System.exit(0);
}
});
}

public static void main(String[] args) {
// new Test4();这句话打开就报错,本来兴致满满想要做界面的,结果界面都出不来
try {
DatagramSocket dsend = new DatagramSocket();
DatagramSocket drece = new DatagramSocket(10004);
new Thread(new Send(dsend)).start();
new Thread(new Rece(drece)).start();
} catch (Exception e) {
throw new RuntimeException("监听端口失败");
}
}
}

class Send implements Runnable {
private DatagramSocket ds;

Send(DatagramSocket ds) {
this.ds = ds;
}

public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));// 用到了缓冲区,为什么没有刷新操作,在哪里刷新??
String line = null;
while ((line = bufr.readLine()) != null) {
if (line.equals("886"))
break;// 用break语句根本停不下来,这里虽然while循环结束,但是其他线程还在运行,所以停不下来
// System.exit(0);
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("127.0.0.1"), 10003);// ?怎么写这个包收到的长度??
System.out.println("我::" + line);
ds.send(dp);
}
} catch (Exception e) {
throw new RuntimeException("发送消息失败");
}
}
}

class Rece implements Runnable {
private DatagramSocket ds;

Rece(DatagramSocket ds) {
this.ds = ds;
}

public void run() {
try {
while (true) {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + "来自dos命令行:" + data);
}
} catch (Exception e) {
throw new RuntimeException("接收消息失败");
}
}
}

UDP传输协议小结:

1,只要是网络传输,必须有socket 。
2,数据一定要封装到数据包中,数据包中包括目的地址、端口、数据等信息。

直接操作udp不可能,对于java语言应该将udp封装成对象,易于我们的使用,这个对象就是DatagramSocket. 封装了udp传输协议的socket对象。

因为数据包中包含的信息较多,为了操作这些信息方便,也一样会将其封装成对象。这个数据包对象就是:DatagramPacket.通过这个对象中的方法,就可以获取到数据包中的各种信息。
DatagramSocket具备发送和接受功能,在进行udp传输时,需要明确一个是发送端,一个是接收端。

udp的发送端:
1,建立udp的socket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。
2,明确要发送的具体数据。
3,将数据封装成了数据包。
4,用socket服务的send方法将数据包发送出去。
5,关闭资源。
--------------------------------------------------------------

import java.net.*;
class  UdpSend{
public static void main(String[] args)throws Exception {
// 1,建立udp的socket服务。
DatagramSocket ds = new DatagramSocket(8888);//指定发送端口,不指定系统会随机分配。
// 2,明确要发送的具体数据。
String text = "udp传输演示 哥们来了";
byte[] buf = text.getBytes();
// 3,将数据封装成了数据包。
DatagramPacket dp = new DatagramPacket(buf,
buf.length,InetAddress.getByName("10.1.31.127"),10000);
// 4,用socket服务的send方法将数据包发送出去。
ds.send(dp);
// 5,关闭资源。
ds.close();
}
}
-------------------------------------------------------------
udp的接收端:
1,创建udp的socket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。
2,定义数据包,用于存储接收到数据。
3,通过socket服务的接收方法将收到的数据存储到数据包中。
4,通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。
5,关闭资源。
-------------------------------------------------------------
class UdpRece {
public static void main(String[] args) throws Exception{
// 1,创建udp的socket服务。
DatagramSocket ds = new DatagramSocket(10000);
// 2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
// 3,通过socket服务的接收方法将收到的数据存储到数据包中。
ds.receive(dp);//该方法是阻塞式方法。
// 4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());//将字节数组中的有效部分转成字符串。
System.out.println(ip+":"+port+"--"+text);
// 5,关闭资源。
ds.close();

接下来完整的实现界面的聊天程序代码

//主函数类

package chatB;
public class MainTest {
  public static void main(String[] args)throws Exception {
ChatView cv=new ChatView();
UdpSR  udpsr=new UdpSR();
udpsr.setUpTxt(cv.getUpTxt());
new Thread(udpsr).start();
}
}
//发送端与输出端定义及功能实现
package chatB;
import java.net.DatagramSocket;
import java.awt.TextArea;
import java.net.DatagramPacket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.net.InetAddress;
class  UdpSR implements Runnable
{  
private DatagramSocket dsSend;
private DatagramSocket dsReceive;
private TextArea upTxt;

public void setUpTxt(TextArea upTxt){
this.upTxt=upTxt;
}
//发送端
public  void sendInfo(String str,int sendPort,int receivePort)
{   
try{
dsSend=new DatagramSocket(sendPort);
byte[] bu=str.getBytes();
DatagramPacket dp=new DatagramPacket(bu,bu.length,InetAddress.getByName("127.0.0.1"),receivePort);
dsSend.send(dp);
dsSend.close();
}catch(Exception e)
{
throw new RuntimeException(e.toString());
}
}
//接收端
public void receiveInfo(int receivePort)
{
try{
dsReceive=new DatagramSocket(receivePort);
DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

while (true)
{
byte[] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,buf.length);
dsReceive.receive(dp);
upTxt.append("A  "+df.format(new Date())+"\n\n"+new String(buf,0,dp.getLength())+"\n\n");
}
}catch(Exception e)
{
throw new RuntimeException(e.toString());
}
    }
public void run()
{
receiveInfo(10003);
}
}
//界面事件处理类
package chatB;
import java.awt.Button;
import java.awt.Frame;
//import java.awt.Button;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ChatViewEvent extends WindowAdapter{
    private Frame chatFrame;
    private TextArea upTxt ,downTxt;
    private Button sendBtn;
public ChatViewEvent(Frame chatFrame,TextArea upTxt,TextArea downTxt,Button sendBtn)
{
this.chatFrame=chatFrame;
this.upTxt=upTxt;
this.downTxt=downTxt;
this.sendBtn=sendBtn;
frameEvent();
sendBtn();

}
    //窗体的事件
public  void frameEvent(){
    chatFrame.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
    // TODO Auto-generated method stub
    //chatFrame.setVisible(false);
System.exit(0);
    }
});
    
}
//按钮的事件
public  void sendBtn(){
       sendBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str=downTxt.getText();
if(str!=null&&!"".equals(str)){
upTxt.append("我 "+df.format(new Date())+"\n\n"+str+"\n\n");
downTxt.setText("");
new UdpSR().sendInfo(str,10000,10001);
}
}
});
}
}

package chatB;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
//界面图形化类
public class ChatView {
    private Frame chatFrame;
    private TextArea upTxt ,downTxt;
    private Button sendBtn;
    private Panel p1,p2,p3;
    public ChatView(){ 
    init();
    }
public TextArea getUpTxt(){
return upTxt;
}
    //初始化控件
    public void init(){
       chatFrame=new Frame("B");
       
       p1=new Panel(new FlowLayout());
       p2=new Panel(new FlowLayout());
       p3=new Panel(new FlowLayout());
       
       upTxt=new TextArea(12, 50);
       downTxt=new TextArea(5,50);
       
       sendBtn=new Button("发送");
       sendBtn.setSize(6, 4);
       
       p1.add(upTxt);
       p1.setSize(400, 300);
       p3.add(downTxt);
       p3.setSize(400,50);
       p2.add(sendBtn);
       p2.setSize(400,150);
       
       chatFrame.setBounds(400, 250, 400, 380);
       //chatFrame.setLayout(new FlowLayout());
       
       chatFrame.add(p1,BorderLayout.NORTH);
       chatFrame.add(p2,BorderLayout.CENTER);
       chatFrame.add(p3,BorderLayout.SOUTH);
       
       chatFrame.setVisible(true);
       new ChatViewEvent(chatFrame,upTxt,downTxt,sendBtn);
    }
    
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值