UDP Socket 通信

UDP聊天应用实践
本文介绍了一个基于UDP协议的简易在线聊天软件实现。该应用可在Android设备上运行,支持用户输入消息并通过UDP发送至指定IP地址及端口。同时,应用能够接收来自同一网络内的消息并显示。

  最近的工作将用到UDP通信,为此,自己写了个通过UDP协议发送和接收数据的小小的在线聊天软件。贴上主要代码:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;

 

/**
* @author Eric Liu
* Date 2012-3-5
* Describe Main Activity of the chatten application.-
* Copyright Kingsun 2011-2012
*/

public class ChattenActivity extends Activity {
private static String IP="192.168.1.117"; //IP address
private static int PORT=3456; //port number
private TextView tv_showMessage; //show messages
private EditText et_message; //for input message
private Button bt_send; //send button
private final static int ITEM0=0; //menu 0
private ReceiveMessage receive; //the receiver thread
private boolean receivable=false; //wether the receiver can receive data
private ScrollView sv_list; //ScrollView
private String localip=""; //the local ip address

private Handler handler=new Handler(){

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
String message=msg.getData().getString("message");
String messages=tv_showMessage.getText().toString();
tv_showMessage.setText(messages+"\n"+message);
//sv_list.fullScroll(View.FOCUS_DOWN);
sv_list.post(new Runnable() {
public void run() {
sv_list.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}

};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intViews();
localip=getLocalIpAddress();
receivable=true;
receive=new ReceiveMessage();
receive.inti();
receive.start();
}

private void intViews()
{
tv_showMessage=(TextView) this.findViewById(R.id.tv_messages);
et_message=(EditText) this.findViewById(R.id.et_message);
bt_send=(Button) this.findViewById(R.id.bt_send);
bt_send.setOnClickListener(new SendClick());
sv_list=(ScrollView) this.findViewById(R.id.sv_list);
}

//get the local ip address
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {

}
return null;
}

//send message button click listener
class SendClick implements OnClickListener
{

public void onClick(View v) {
// TODO Auto-generated method stub
String oldMessages="";
String inputMessage="";
oldMessages=tv_showMessage.getText().toString();
inputMessage=et_message.getText().toString().trim();
oldMessages=oldMessages+"\n"+"我:"+"\n"+inputMessage+"\n\n";
//if user do not input empty message
if(inputMessage!=null && !inputMessage.equals(""))
{
sendMessage(IP,PORT,inputMessage);
et_message.setText("");
tv_showMessage.setText(oldMessages);
sv_list.post(new Runnable() {
public void run() {
sv_list.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
}

}

//send message via UDP
private void sendMessage(String ipaddr,int port,String message)
{
DatagramSocket socket=null;
InetAddress addr=null;
String sendContent=localip+":\n"+message+"\n\n";

try {
addr=InetAddress.getByName(ipaddr);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(addr==null) return;

try {
socket=new DatagramSocket();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(socket==null) return;

//int lenth=sendContent.length();
System.out.println("send message:"+sendContent);

byte[] messBytes=null;
try {
messBytes = sendContent.getBytes("gb2312");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(messBytes==null) return;
DatagramPacket packet=new DatagramPacket(messBytes, messBytes.length, addr, port);

try {
socket.send(packet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
menu.add(0, ITEM0, 1, ChattenActivity.this.getResources().getString(R.string.menu_setting));
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
switch(item.getItemId())
{
case ITEM0:
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.alert_dialog_text_entry, null);
final EditText et_ip=(EditText) textEntryView.findViewById(R.id.et_address);

new AlertDialog.Builder(ChattenActivity.this)
.setIcon(R.drawable.alert_dialog_icon)
.setTitle(R.string.setting_title)
.setView(textEntryView)
.setPositiveButton(R.string.bt_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
IP=et_ip.getText().toString().trim();
receive.inti();
/* User clicked OK so do some stuff */
}
})
.setNegativeButton(R.string.bt_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {

/* User clicked cancel so do some stuff */
}
})
.create().show();
break;
}
return super.onOptionsItemSelected(item);
}

//receive message thread
class ReceiveMessage extends Thread
{

byte[] messageBytes=new byte[1024];
DatagramSocket datagramSocket=null;
DatagramPacket datagramPacket=null;

public void inti()
{
try {
datagramSocket=new DatagramSocket(PORT);
datagramSocket.setReuseAddress(true);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

datagramPacket = new DatagramPacket(messageBytes,messageBytes.length);

}

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("running");
while(receivable)
{
try {
datagramSocket.receive(datagramPacket);
String message=new String(datagramPacket.getData(),0,datagramPacket.getLength(),"gb2312");
Message msg=new Message();
Bundle data=new Bundle();
System.out.println(message);
data.putCharSequence("message", message);
msg.setData(data);
handler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
datagramSocket.close();
datagramSocket.disconnect();
}

}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
receivable=false;
receive=null;
System.exit(0);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
switch(keyCode)
{
case KeyEvent.KEYCODE_BACK:
receivable=false;
finish();
System.exit(0);
}
return super.onKeyDown(keyCode, event);
}

}

转载于:https://www.cnblogs.com/gdouhuajie/archive/2012/03/06/Eric.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值