首先展示Android设备和PC端的界面:
步骤:
首先,PC端按下“接收”按钮,使PC端进入接收状态;
此时,Android端输入框输入数据后,按下“发送”,可以将输入框上的数据发送到PC端。
接着,在PC端上方的发送框输入数据,按下发送,可以将数据发送到Android端,数据显示在LogCat日志上。
有关发送的原理,我在我的上一篇博客里已经简单说明啦,所以在此不做介绍,把代码拿出来,说明几个需要注意的地方。
上一篇链接:怎样实现UDP通信,使Android设备上的数据成功发送到PC机上?
Android端代码如下:
public class SendActivity extends Activity {
DatagramSocket Socket;
int DuanKouShou = 3013; //用来接收数据的端口,假设端口号为3013
int DuanKouFa = 4013; //用来发送的端口,假设端口号为4013
/*
值得注意的是:要想把数据发送和接收无误,
Android端用于接收的端口,与PC端用于发送的端口,端口号要一致 ;
Android端用于发送的端口,与PC端用于接收的端口,端口号要一致。
*/
Thread TSend; //发送线程,相当于建立一个Android端用于发送数据的平台
Thread threadRece; //接收线程,同上
@Override
//发送方是“手机”
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send);
Button Bt1 = (Button)this.findViewById(R.id.bt1);
Button Bt2 = (Button)this.findViewById(R.id.bt2);
final EditText et = (EditText)this.findViewById(R.id.eT1);
//创建好界面图标,并与程序连接
Bt1.setOnClickListener(new OnClickListener(){
//当按下按钮时,执行以下方法
public void onClick(View v) {
// TODO Auto-generated method stub
TSend = new Thread(){
public void run(){
String str = et.getText().toString();//获取输入框的信息
Log.v("fist","可以发送:"+ str);
SendMsg(str); //只要一按按钮,就发送数据
if(Socket!=null)
Socket.close();
}
};
TSend.start();
Log.v("fist","线程执行完啦!");
}
});
Bt2.setOnClickListener(new OnClickListener(){
//当按下“接收”按钮后,开始执行接收操作
public void onClick(View v) {
new Thread(){
public void run(){
try {
//接收方法在此调用哟
receiveMsg();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v("fist","是手机接受异常!" + e);
}
}
}.start();
}
});
}
private void receiveMsg() throws Exception{
//Android端的接收方法
Log.v("fist", "手机数据接收开始");
//Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
try {
Socket = new DatagramSocket(DuanKouFa);
byte[] data=new byte[1024];
DatagramPacket pack = new DatagramPacket(data, data.length);
Socket.receive(pack); //关键问题: 在这里卡住了!收不到消息
int len = pack.getLength();
byte[] tong = new byte[len];
for(int i = 0 ; i < len ; i++ )
tong[i] = data[i];
String str=new String(tong);
//
Log.v("fist", "接收成功,消息为: " + str );
// Socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v("fist", " 接收异常 ,异常为 : " + e +"\n"+e.getLocalizedMessage());
// Toast.makeText(this, "接收异常" + e, Toast.LENGTH_LONG).show();
}
}
private void SendMsg(String msg){
//Android端的发送方法
Log.v("fist", "开始发送!");
try {
Socket = new DatagramSocket(DuanKouFa);
InetAddress serverAddress = InetAddress.getByName("192.168.43.84");
byte data[] = msg.getBytes();//把要发送的数据转化为Byte形式
DatagramPacket package1 = new DatagramPacket(data,data.length,
serverAddress,DuanKouShou);//设置一个发送包(相当于快递,写了快递的地址和编号)
Socket.send(package1);//发送快递
Log.v("fist", "发送成功!");
} catch (Exception e) {
// TODO Auto-generated catch block
Log.v("fist", "发送异常"+ e);
e.printStackTrace();
}
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.send, menu);
return true;
}
}
PC端代码:
public class UDPServer extends JFrame{
DatagramSocket socket ; //这个类的快递员
final int DuanKouFa = 4013; //这个站点的“发送”端口
final int DuanKouShou = 3013; //这个站点用来接收的端口;
public void init(){
this.setTitle("发送接受器");
this.setSize(400,400);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
FlowLayout fl = new FlowLayout();
this.setLayout(fl);
final JTextField Tx = new JTextField();
Tx.setPreferredSize(new Dimension(300,50));
this.add(Tx);
JButton bt1 = new JButton("发送");
this.add(bt1);
bt1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String name = e.getActionCommand();
System.out.println("输出信息:" + name);
new Thread()//当下这个线程已经没问题了
{
public void run(){
String str = Tx.getText();
SendMsg(str);
System.out.println("数据发送成功: " + str);
}
}.start();
if(socket!=null)
socket.close();
System.out.println("端口关闭? " + socket.isClosed());//这里也可以执行到
}
});
final JTextField Tx2 = new JTextField();
Tx2.setPreferredSize(new Dimension(300,50));
this.add(Tx2);
JButton bt2 = new JButton("接收");
this.add(bt2);
bt2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
String name = arg0.getActionCommand();
System.out.println("输出信息:" + name);
names = "接收";
new Thread()
{
public void run(){
try {
receiveMsg();
if(socket != null)
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("接收异常: " + e);
}
}
}.start();
}
});
this.setVisible(true);
}
private int Ip;
private InetAddress Ipt;
private String names = "";
private String St = "";
private void SendMsg(String msg){
System.out.println(" ");
System.out.println("电脑开始发送!");
try {
socket = new DatagramSocket(DuanKouFa);
byte data[] = msg.getBytes();//把要发送的数据转化为Byte形式
DatagramPacket package1 = new DatagramPacket(data,data.length,
Ipt,Ip);//设置一个发送包(相当于快递,写了快递的地址和编号)
System.out.println("发送端口号为: " + Ip);
System.out.println("发送Ip地址为: " + Ipt);
socket.send(package1);//发送快递
System.out.println("发送成功!");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("发送异常,异常为: " + e);
e.printStackTrace();
}//设置端口号,
}
private void receiveMsg() throws Exception{
System.out.println("数据接受开始!!!!" );
try {
socket = new DatagramSocket(DuanKouShou);
byte[] data=new byte[1024];
DatagramPacket pack = new DatagramPacket(data, data.length);
socket.receive(pack);
int len = pack.getLength();
byte[] tong = new byte[len];
for(int i = 0 ; i < len ; i++ )
tong[i] = data[i];
Ip = pack.getPort();
Ipt = pack.getAddress();
System.out.println("获取的端口号为:" +Ip );
System.out.println("获取的IP地址为:" +Ipt );
String str=new String(tong);
System.out.println("收到信息: "+ str);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("接收异常! "+ e);
}
}
public static void main(String[] args)throws Exception {
UDPServer UDps = new UDPServer();
UDps.init();
}
几个值得注意的地方:
1、要想成功发送和接收数据,Android端用于发送的端口与PC端用于接收的端口,端口号要一致;Android端用于接收的端口与PC端用于发送的端口,端口号要一致;
2、满足上条后,还要满足:Android端用于发送的IP地址与PC端用于接收的IP地址一致;Android端用于接收的IP地址与PC端用于发送的IP地址一致;
3、由于Android端发送数据所用的IP地址与端口号事先不明,因此,在PC端设置2个变量:
private int Ip;
private InetAddress Ipt;
先从Android端获取数据,获取数据的同时,用变量Ip获取Android端发送的端口号;用变量Ipt获取Android端发送用的IP地址。
此时,从PC端发送数据到Android端。