我正在尝试将带有Android的UDP数据包发送到我的计算机上用C#编写的服务器。当我在手机上运行应用程序时,我会收到非法状态异常。我认为这可能与在主要活动上执行网络操作有关,但我不知道如何解决这个问题。这是我的客户:
public class MainActivity extends Activity {
WifiManager wifi;
InetAddress dev_ip;
final int serverPort = 31337;
Thread drawThread = new Thread(new drawer());
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set up wifi and connection
wifi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = wifi.getConnectionInfo();
int ip = info.getIpAddress();
String ipaddr = (ip & 0xff) + "." + (ip >> 8 & 0xff) + "." + (ip >> 16 & 0xff) + "." + (ip >> 24 & 0xff);
try {
dev_ip = InetAddress.getByName(ipaddr);
} catch (UnknownHostException e) {
Toast.makeText(this, "host error", Toast.LENGTH_LONG).show();
}
if (!wifi.isWifiEnabled())
wifi.setWifiEnabled(true);
Toast.makeText(this, "IP: " + ipaddr, Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void draw(View view) throws IOException, SocketException
{
drawThread.start();
}
public class drawer implements Runnable {
public void run() {
//transmit data
try {
DatagramSocket socket = new DatagramSocket(serverPort, /*myip*/);
String test_data = "It works!";
byte btest[] = new byte[50];
btest = test_data.getBytes();
DatagramPacket p1 = new DatagramPacket(btest, btest.length, /*myip*/, serverPort);
socket.send(p1);
socket.close();
}
catch (IOException e) {
}
}
}
}
logcat的:
07-27 00:10:17.155: D/CLIPBOARD(1711): Hide Clipboard dialog at Starting input:
finished by someone else... !
07-27 00:10:18.020: W/System.err(1711): java.net.BindException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)
07-27 00:10:18.020: W/System.err(1711): at libcore.io.IoBridge.bind(IoBridge.java:89)
07-27 00:10:18.020: W/System.err(1711): at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:68)
07-27 00:10:18.020: W/System.err(1711): at java.net.DatagramSocket.createSocket(DatagramSocket.java:133)
07-27 00:10:18.020: W/System.err(1711): at java.net.DatagramSocket.<init>(DatagramSocket.java:95)
07-27 00:10:18.020: W/System.err(1711): at com.ls.styloid.MainActivity$drawer.run(MainActivity.java:67)
07-27 00:10:18.025: W/System.err(1711): at java.lang.Thread.run(Thread.java:856)
07-27 00:10:18.025: W/System.err(1711): Caused by: libcore.io.ErrnoException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)
07-27 00:10:18.025: W/System.err(1711): at libcore.io.Posix.bind(Native Method)
07-27 00:10:18.025: W/System.err(1711): at libcore.io.ForwardingOs.bind(ForwardingOs.java:39)
07-27 00:10:18.025: W/System.err(1711): at libcore.io.IoBridge.bind(IoBridge.java:87)
07-27 00:10:18.025: W/System.err(1711): ... 5 more
07-27 00:10:42.090: D/CLIPBOARD(1711): Hide Clipboard dialog at Starting input: finished by someone else... !
07-27 00:11:30.150: W/System.err(2535): java.net.BindException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)
07-27 00:11:30.155: W/System.err(2535): at libcore.io.IoBridge.bind(IoBridge.java:89)
07-27 00:11:30.155: W/System.err(2535): at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:68)
07-27 00:11:30.155: W/System.err(2535): at java.net.DatagramSocket.createSocket(DatagramSocket.java:133)
07-27 00:11:30.155: W/System.err(2535): at java.net.DatagramSocket.<init>(DatagramSocket.java:95)
07-27 00:11:30.155: W/System.err(2535): at com.ls.styloid.MainActivity$drawer.run(MainActivity.java:67)
07-27 00:11:30.155: W/System.err(2535): at java.lang.Thread.run(Thread.java:856)
07-27 00:11:30.155: W/System.err(2535): Caused by: libcore.io.ErrnoException: bind failed: EADDRNOTAVAIL (Cannot assign requested address)
07-27 00:11:30.155: W/System.err(2535): at libcore.io.Posix.bind(Native Method)
07-27 00:11:30.155: W/System.err(2535): at libcore.io.ForwardingOs.bind(ForwardingOs.java:39)
07-27 00:11:30.155: W/System.err(2535): at libcore.io.IoBridge.bind(IoBridge.java:87)
07-27 00:11:30.155: W/System.err(2535): ... 5 more
07-27 00:11:36.515: D/CLIPBOARD(2535): Hide Clipboard dialog at Starting input: finished by someone else... !
编辑:服务器似乎有很多问题,我之前没有注意到。当我根据其中一个答案重写听众时,他们就开始发生了。我有时会使用label3,套接字异常0x80004005获取“无法访问已处置对象”错误,并且仍然没有收到数据包。但是,在检查套接字状态时,它似乎是可读的。我可能搞砸了线程,请帮我解决这个问题。
服务器:
public partial class Form1 : Form
{
Socket listener;
Thread udp_listener;
public Form1()
{
InitializeComponent();
//set up listener thread
udp_listener = new Thread(listen);
udp_listener.IsBackground = true;
udp_listener.Start();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
listener.Close();
udp_listener.Join();
}
private void listen()
{
//set up UDP
const int serverPort = 31337;
bool terminate = false;
IPHostEntry iphost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipaddr = iphost.AddressList[0];
IPEndPoint endpoint = new IPEndPoint(ipaddr, serverPort);
listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
label3.Text = ipaddr.ToString();
try
{
do
{
byte[] buffer = new byte[100];
listener.Receive(buffer);
label3.Text = "Connected";
label3.ForeColor = Color.Red;
label3.Text = Encoding.UTF8.GetString(buffer);
}
while (!terminate);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
finally
{
listener.Close();
}
listener.Close();
}
}
EDIT2:
我尝试在计算机上使用C#创建客户端。数据包已发送,但我的服务器没有收到任何内容。
EDIT3: 服务器现在工作正常,但Android应用程序拒绝运行。这是代码:
package com.tests.contest;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
public class MainActivity extends Activity {
private Socket sock;
private BufferedWriter out;
private Thread thrd;
@Override
public void onResume() {
super.onResume();
thrd = new Thread(new Runnable() {
public void run() {
while (!Thread.interrupted()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
sock = new Socket("THEIP", 31337);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out = new BufferedWriter(new OutputStreamWriter(sock
.getOutputStream()));
out.write("WORKS");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
});
thrd.start();
}
@Override
public void onPause() {
super.onPause();
if (thrd != null)
thrd.interrupt();
try {
if (sock != null) {
sock.getOutputStream().close();
sock.getInputStream().close();
sock.close();
}
} catch (IOException e) {}
thrd = null;
}
/*private void sendText() {
String text = "HI";
try {
out.write(text + "\n");
out.flush();
} catch (IOException e) {}
}*/
}
问题出现是因为我在主线程上运行网络操作,我显然没有这样做。
答案 0 :(得分:7)
该异常告诉您确切要做什么:在单独的Socket
中创建Thread
对象。您也可以使用AsyncTask
。
在主UI线程上不允许Sockets
背后的原因是它可能导致应用程序从等待Application Not Responding
获取可怕的Socket
消息。
您可以跳到客户端示例,因为您已有桌面服务器。
edit2 :由于我恰好在我的Android应用程序的C#服务器上工作,这是我的桌面应用程序如何创建一个监听器Socket
:
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 27015); //Port 27015
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp); // Create a TCP/IP socket.
我几乎可以肯定问题出在您的服务器/网络中。发送简单UDP数据包的Android代码看起来是正确的。您可能还想尝试通过编写简单的C#客户端程序来连接localhost
或127.0.0.1
。
编辑3:
使用此基本应用程序,您应该能够在输入正确的IP地址后连接到服务器。按发送将向服务器发送一些字节。使用此选项可确保连接正常。我已经确认它适用于我。如果这样可行,那么我会针对您的服务器问题打开一个新的SO问题,否则您的网络配置会出现问题。
答案 1 :(得分:2)
我认为这个问题来自do while循环,因为你试图在循环中修改一个UI组件(label3),这就是无限循环错误 terminate 变量<强>总是假的。尝试获取代码,从而修改UI(label3。*)。[/ p>