前言
原创文章欢迎转载,请保留出处。
若有任何疑问建议,欢迎回复。
邮箱:[email protected]
本人学习java中的socket练手的小程序,高手请飘过,仅作为学习笔记,没有技术含量。
分析
这里使用两个独立线程负责发包和收包,设计两个类实现Runnable接口,利用管道和主窗体通信。
代码
mainfest.txt文件:这里注意有myqq.MyQQ后的回车符和myqq.MyQQ前的空格
Main-Class: myqq.MyQQ
MyQQ.java文件:
package myqq;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
class UdpSend implements Runnable
{
private DatagramSocket ds;
private InputStream is;
public UdpSend(DatagramSocket ds,InputStream is)
{
try
{
this.ds = ds;
this.is = is;
}
catch (Exception e)
{
throw new RuntimeException("发送端错误");
}
}
public void run()
{
try
{
//读取来自文本框的数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = null;
while((s=br.readLine())!=null)
{
//当输入886时停止发送数据
if("886".equals(s))
break;
byte[] buf = s.getBytes();
//这里是要发送数据包的目标ip和端口,也可以设置成广播地址
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.255.255"),12345);
ds.send(dp);
}
br.close();
ds.close();
}
catch (Exception e)
{
throw new RuntimeException("发送端错误");
}
}
}
class UdpRecv implements Runnable
{
private DatagramSocket ds;
private OutputStream is;
public UdpRecv(DatagramSocket ds,OutputStream is)
{
try
{
this.ds = ds;
this.is = is;
}
catch (Exception e)
{
throw new RuntimeException("接收端错误");
}
}
public void run()
{
try
{
while(true)
{
//Udp最大的数据包长度是64k
byte[] buf = new byte[1024*64];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
//获取数据包的源ip和数据内容
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
String s = ip+"::"+data;
is.write(s.getBytes());
is.flush();
}
}
catch (Exception e)
{
throw new RuntimeException("接收端错误");
}
}
}
class MyQQ
{
private static Frame r;
private static TextArea tsend;//发送文本框
private static TextArea trecv;//接收文本框
//发送通信管道
private static PipedInputStream sis;
private static PipedOutputStream sos;
//接收通信管道
private static PipedInputStream ris;
private static PipedOutputStream ros;
public static void main(String[] args) throws Exception
{
DatagramSocket sendds = new DatagramSocket();
DatagramSocket recvds = new DatagramSocket(12345);//监听的端口
sis = new PipedInputStream();
sos = new PipedOutputStream();
sis.connect(sos);
ris = new PipedInputStream();
ros = new PipedOutputStream();
ris.connect(ros);
//启动发送和接收线程
new Thread(new UdpRecv(recvds,ros)).start();
new Thread(new UdpSend(sendds,sis)).start();
System.out.println("Hello MyQWQ!");
init();
while(true)
{
byte[] buf = new byte[1024];
int len = ris.read(buf);
trecv.append(new String(buf,0,len)+"\r\n");
}
}
public static void init() throws IOException
{
r = new Frame("MyQQ");
trecv = new TextArea("",20,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
tsend = new TextArea("",13,50,TextArea.SCROLLBARS_VERTICAL_ONLY);
r.setBounds(400,100,400,600);
r.setLayout(new FlowLayout());
r.add(trecv);
r.add(tsend);
//Frame事件
event();
r.setVisible(true);
//设置输入框为当前焦点
trecv.transferFocus();
}
public static void event()
{
r.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
tsend.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)//回车键发送数据
{
e.consume();
try
{
sos.write((tsend.getText()+"\r\n").getBytes());
sos.flush();
//System.out.println(tsend.getText());
}
catch (Exception ex)
{
throw new RuntimeException("IO错误");
}
tsend.setText("");
}
}
});
}
}
编译和打包
到文件目录下编译,也可以使用IDE建工程
javac -d . MyQQ.java
jar cvfm myqq.jar mainfest.txt myqq
运行效果
直接运行打包的myqq.jar:(由于只有一台电脑,地址写的是广播地址,能收到证明程序成功发出并收到包)
时间: 2024-12-21 07:58:19