我有以下设置: 我的计算机是一个通过WiFi适配器的热点,其上运行着一个服务器应用程序(代码无关紧要,丑陋但我可以发布,如果它很重要)。我的电脑的IP地址是192.168.66.1。
我写了一个向它发送UDP数据包的android应用程序,如果我将它发送到255.255.255.255,该数据包只会出现在wireshark上。如果我尝试将目标更改为192.168.66.255或192.168.66.1,它就不会出现在wireshark上,并且设备上没有报告错误。 (我在尝试单播时也将套接字更改为广播(false))
这是不起作用的发送代码:
public class ClientThread implements Runnable {
public ClientThread()
{
super();
}
private void sendCmd(DatagramSocket s, ByteArrayOutputStream cmd) throws Exception
{
InetAddress inet;
inet = getBroadcastAddress(getApplicationContext());
Log.d("ScreenToggler", inet.toString());
//DatagramPacket dataPacket = new DatagramPacket(cmd.toByteArray(), cmd.toByteArray().length, InetAddress.getByName("255.255.255.255"), ScreenToggler.SERVERPORT);
//s.setBroadcast(true);
DatagramPacket dataPacket = new DatagramPacket(cmd.toByteArray(), cmd.toByteArray().length, InetAddress.getByName("192.168.66.1"), ScreenToggler.SERVERPORT);
s.setBroadcast(false);
s.send(dataPacket);
Log.d("ScreenToggler", "Sent packet");
}
public void run() {
DatagramSocket socket = null;
try
{
try
{
socket = new DatagramSocket(ScreenToggler.SERVERPORT);
}
catch(Exception e)
{
Log.e("ScreenToggler", "S: Error", e);
return;
}
Log.d("ScreenToggler", "C: Connecting...");
System.out.println(CmdToSend.toByteArray().length);
sendCmd(socket, CmdToSend);
socket.close();
}
catch (Exception e)
{
Log.e("ScreenToggler", "S: Error", e);
try
{
socket.close();
}
catch(Exception e2)
{}
}
}
}
当我尝试使用此代码发送时,没有异常发生,流程继续正常,并且wireshark上没有任何内容。没有任何迹象表明出现了问题 - 例如我的机器人拒绝发送数据包。
如果我取消注释两行
//DatagramPacket dataPacket = new DatagramPacket(cmd.toByteArray(), cmd.toByteArray().length, InetAddress.getByName("255.255.255.255"), ScreenToggler.SERVERPORT);
//s.setBroadcast(true);
并重新评论他们的两个相应的行,数据包出现在wireshark上,并在我的计算机上的服务器应用程序上正确接收。我的电脑的防火墙已关闭。
这是我的权限清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="zomg.screenshutter"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="zomg.screenshutter.ScreenToggler"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
我有其他可能相关的信息是我的android的IP地址是192.168.66.101,它识别192.168.66.1作为其网关(当我尝试通过wifi管理器获取网关地址时,它确实返回我的计算机的地址)。 / p>
我不知道我在这里缺少什么?
答案 0 :(得分:0)
我刚刚建立了一个套接字类。我测试了它
如果你发送广播,你需要知道你的ip-address(192.168.178.14)和你的新掩码(255.255.255.0)上建立的braodcast地址。只需在shell中键入“ifconfig”,然后在“Bcast”后看到ip。你也需要一个端口号,对我而言总是9999(选择一个1024,因为下面的每个数字都保留给其他服务)
public class SocketService {
private Handler mHandler;
// threads
private UDPReceiveThread mUDPReceiveThread;
// UDP
private DatagramSocket mUDPSendSocket;
private DatagramPacket mUDPPacket;
private byte[] mUDPSendData;
public SocketService(Handler handler) {
mHandler = handler;
try {
mUDPReceiveThread = new UDPReceiveThread(9999);
mUDPReceiveThread.start();
} catch (SocketException e) {
e.printStackTrace();
}
try {
mUDPSendSocket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
}
public void close() {
try {
mUDPSendSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void writeUDP(String message, String address, int port) {
if (null == mUDPSendData)
mUDPSendData = new byte[1024];
if (null != mUDPSendSocket) {
InetAddress ipAddress;
try {
ipAddress = InetAddress.getByName(address);
mUDPSendData = message.getBytes();
mUDPPacket = new DatagramPacket(mUDPSendData, mUDPSendData.length, ipAddress, port);
new UDPSendThread().start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class UDPSendThread extends Thread {
public void run() {
try {
mUDPSendSocket.send(mUDPPacket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class UDPReceiveThread extends Thread {
private DatagramSocket tReceiveSocket;
DatagramPacket tReceivePacket;
private byte[] tReceiveData;
private String tMessage = null;
public UDPReceiveThread(int port) throws SocketException {
tReceiveSocket = new DatagramSocket(port);
tReceiveData = new byte[1024];
tReceivePacket = new DatagramPacket(tReceiveData, tReceiveData.length);
}
public void run() {
while (true) {
try {
tReceiveSocket.receive(tReceivePacket);
tMessage = new String(tReceivePacket.getData(), "UTF-8").substring(0, tReceivePacket.getLength());
mHandler.obtainMessage(MainActivity.MESSAGE_NEW_UDP_DATA, tReceivePacket.getLength(), -1, tMessage).sendToTarget();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
这是我使用类
的MainActivitypublic class MainActivity extends Activity {
private SocketService mService;
private String mUdpSendIp = "192.168.178.255";
//views
private Button bUdpSend;
//messages
public static final int MESSAGE_NEW_UDP_DATA = 1;
public static final int MESSAGE_NEW_TCP_DATA = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mService = new SocketService(mHandler);
//find views
TextView tvUdpTitle = (TextView)findViewById(R.id.tv_udpTitle);
bUdpSend = (Button)findViewById(R.id.b_udpSend);
//configure views
tvUdpTitle.setTextColor(getResources().getColor(R.color.textBlue));
bUdpSend.setOnClickListener(new buttonListener());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class buttonListener implements OnClickListener {
@Override
public void onClick(View v) {
if(v.equals(bUdpSend)) {
EditText etUdpMessage = (EditText)findViewById(R.id.et_udpMessage);
mService.writeUDP(etUdpMessage.getText().toString(), mUdpSendIp, 9999);
}
}
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case MESSAGE_NEW_UDP_DATA:
String message = (String) msg.obj;
TableLayout tl_udpReceive = (TableLayout) findViewById(R.id.tl_udpReceive);
TableRow tr = new TableRow(getApplicationContext());
TextView tvNewMessage = new TextView(getApplicationContext());
tvNewMessage.setText(message);
tvNewMessage.setTextSize(16);
tvNewMessage.setTextColor(getApplicationContext().getResources().getColor(R.color.textBlue));
tr.addView(tvNewMessage);
tl_udpReceive.addView(tr);
final ScrollView tmp = (ScrollView)tl_udpReceive.getParent();
tmp.post(new Runnable() {
@Override
public void run() {
tmp.fullScroll(View.FOCUS_DOWN);
}
});
break;
}
}
};
}