关于android socket通讯,求大神帮看看

dghjkoll 2014-11-13 06:53:32
写了个android与pc端通信的例子,pc端用的是mfc写的,做服务端。想实现以下功能:
android填写完用户名和密码点击登录按钮,android把用户名和密码打包发给pc端,pc端收到后在发出一条消息给android,android收到并解析这条消息后启动一个新Activity。
现在的情况是android能给PC发信息,PC端给android发信息收不到。
这是android的源码:
package com.example.sendtoserver;

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.os.Bundle;
import android.os.Message;
import android.os.StrictMode;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity
{
Socket socket=null;
String ip="192.168.137.1";
int port=8888;
BufferedReader br=null;
BufferedWriter bw=null;
Button loginButton=null;
EditText username=null;
EditText password=null;
ReceiveThread receThread=null;
String receString=null;
InitThread it=null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setContentView(R.layout.activity_main);

loginButton=(Button)this.findViewById(R.id.login);
loginButton.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
// TODO Auto-generated method stub
if(bw!=null)
{
try
{
bw.write("/Cmd Login /username "+username.getText().toString()+" /password "+password.getText().toString()+" /");
bw.flush();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
username=(EditText)this.findViewById(R.id.username);
password=(EditText)this.findViewById(R.id.password);

it=new InitThread();
it.start();
receThread=new ReceiveThread();
receThread.start();
}
class InitThread extends Thread
{

@Override
public void run()
{
// TODO Auto-generated method stub
super.run();
try
{
socket=new Socket(ip,port);
bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
class ReceiveThread extends Thread
{

@Override
public void run()
{
// TODO Auto-generated method stub
super.run();
if(br!=null)
{
try
{
int count=0;
char[] buffer=null;
while(true)
{
if((count=br.read(buffer))>0)
{
break;
}
}
receString=buffer.toString();
String[] cmd=parse(receString);
Intent intent=new Intent();
intent.putExtra("id",(cmd[2].split(" "))[1]);
intent.putExtra("queueId",(cmd[3].split(" "))[1]);
intent.putExtra("queueName",(cmd[4].split(" "))[1]);
intent.setClass(MainActivity.this,ListActivity.class);
(MainActivity.this).startActivity(intent);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private String[] parse(String rece)
{
String[] elem=null;
elem=rece.split("/");
return elem;
}
}
@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;
}
@Override
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
if(socket!=null)
{
try
{
socket.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(br!=null)
{
try
{
br.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(bw!=null)
{
try
{
bw.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// it.destroy();
// receThread.destroy();
}


}
...全文
178 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fearless___ 2015-07-30
  • 打赏
  • 举报
回复
厉害....................
szuzsq 2014-11-14
  • 打赏
  • 举报
回复

#pragma once
#include "thread.h"
#include <string>
#include <vector>

class ISocketCallback {
public:
	virtual void OnBind(thread* owner, int code) = 0; //request by server only. //0: success; else SOCKET_ERROR;
	virtual void OnAccept(thread* owner, thread* socket) = 0; //request by server only. //note: you may also invoke socket->SetCallback() to listen it.
	virtual void OnDisaccept(thread* owner, thread* socket, int code) = 0; //request by server only. //0: success; else SOCKET_ERROR;
	virtual void OnConnect(thread* owner, int code) = 0; //request by client only. //0: success; else SOCKET_ERROR;
	virtual void OnClose(thread* owner, int code) = 0; //request by server & client both. //0: success; else SOCKET_ERROR;
	
	virtual void OnReceive(thread* owner, thread* socket, const char* data, int len) = 0; //request by server & client both. //note: the owner is client
};

class CServerSocketThread: public thread {
public:
	CServerSocketThread();
	virtual ~CServerSocketThread();
	void SetCallback(ISocketCallback* callback);
	
	bool Bind(int port);
	void Close();
	
	int Send(thread* socket, const char* data, int len); //send to the special socket or all connected sockets if null
	void DoReceive(thread* socket, const char* data, int len); //invoked by client
	void DoClose(thread* socket, int code); //invoked by client
protected:
	virtual void OnExecute();
private:
	ISocketCallback* m_callback;
	int m_port;
	std::vector<thread*> m_clients;
	CRITICAL_SECTION m_cs;
};

class CClientSocketThread: public thread {
public:
	CClientSocketThread();
	virtual ~CClientSocketThread();
	void SetCallback(ISocketCallback* callback);
	std::string GetAddress();
	
	bool Accept(SOCKET socket, thread* parent);
	bool Connect(const wchar_t* addr, int port);
	void Close();
	
	int Send(const char* data, int len);
protected:
	virtual void OnExecute();
private:
	//for both accept or connect. but usually connect
	ISocketCallback* m_callback;
	//for accept
	SOCKET m_socket;
	thread* m_parent;
	//for connect
	std::wstring m_addr;
	int m_port;
	//CRITICAL_SECTION m_cs;
};
szuzsq 2014-11-14
  • 打赏
  • 举报
回复

package com.android_daemon.service;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;

interface ISocketCallback {
	public void onBind(Thread owner, int code); //request by server only. //0: success; else SOCKET_ERROR;
	public void onAccept(Thread owner, Thread socket); //request by server only. //note: you may also invoke socket->SetCallback() to listen it.
	public void onDisaccept(Thread owner, Thread socket, int code); //request by server only. //0: success; else SOCKET_ERROR;
	public void onConnect(Thread owner, int code); //request by client only. //0: success; else SOCKET_ERROR;
	public void onClose(Thread owner, int code); //request by server & client both. //0: success; else SOCKET_ERROR;

	public void onReceive(Thread owner, Thread socket, byte[] data, int len); //request by server & client both. //note: the owner is client
};

class ServerSocketThread extends Thread {
	volatile boolean _stop = false;
	private ISocketCallback callback = null;
	private int port = 0;
	private java.util.List<Thread> clients = null;

	public ServerSocketThread() {
		clients = new ArrayList<Thread>();
	}
	public void setCallback(ISocketCallback callback) {
		this.callback = callback;
	}

	public void bind(int port) {
		close();
		_stop = false;
		this.port = port;
	}
	public void close() {
		_stop = true;
		//interrupt();
		try {
			join();
		}
		catch (InterruptedException e) {
		}
		port = 0;
		synchronized (ServerSocketThread.class) {
			clients.clear();
		}
	}

	public void send(Thread socket, byte[] data, int len) { //send to the special socket or all connected sockets if null
		if(socket != null)
			((ClientSocketThread)socket).send(data, len);
		else {
			synchronized (ServerSocketThread.class) {
				for (Thread client : clients) {
					if(client == null)
						continue;
					ClientSocketThread thread = (ClientSocketThread)client;
					thread.send(data, len);
				}
			}
		}
	}
	public void doReceive(Thread socket, byte[] data, int len) { //invoked by client
		if(callback != null)
			callback.onReceive(this, socket, data, len);
	}
	public void doClose(Thread socket, int code) { //invoked by client
		//fixme: to be optimized: when thread run out, the thread object is also in the clients. as so reason--1:occupy more resource; 2:there will send to some invalid socket which has been closed.
		if(callback != null)
			callback.onDisaccept(this, socket, code);
	}

	public void run() {
		try {
			/*************************************
			fd_set fdread;
			timeval timeout;
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;
			
			while(true) {
				FD_ZERO(&fdread);
				FD_SET(sockSrv, &fdread);
				
				if(select(0, &fdread, 0, 0, &timeout) > 0 && FD_ISSET(sockSrv, &fdread)) {
					SOCKET client = accept(sockSrv, 0, 0);
				}
			}			
			*************************************/

			ServerSocket server = new ServerSocket(this.port);
			if(callback != null)
				callback.onBind(this, server != null ? 0 : -1);
			System.out.println("server.bind()-------------------");
			server.setSoTimeout(1000);
			while (!_stop && !server.isClosed()) {
				try {
					Socket socket = server.accept();
					System.out.println("server.accept()------------------" + socket.getInetAddress().getHostAddress() + ":" + socket.getLocalPort());
					ClientSocketThread thread = new ClientSocketThread();
					thread.accept(socket, this);
					thread.start();
					synchronized (ServerSocketThread.class) {
						clients.add(thread);
					}
					if(callback != null)
						callback.onAccept(this, thread);
				}
				catch (SocketTimeoutException e) {
				}
			}

			synchronized (ServerSocketThread.class) {
				for (Thread client : clients) {
					if(client == null)
						continue;
					ClientSocketThread thread = (ClientSocketThread)client;
					thread.close();
				}
				clients.clear();
			}

			server.close();
			if(callback != null)
				callback.onClose(this, server != null ? 0 : -1);
			System.out.println("server.close()-------------------");
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}

class ClientSocketThread extends Thread {
	volatile boolean _stop = false;
	//for both accept or connect. but usually connect
	private ISocketCallback callback = null;
	//for accept
	private Socket socket = null;
	private Thread parent = null;
	//for connect
	private String addr = "";
	private int port = 0;

	public ClientSocketThread() {
	}
	public void setCallback(ISocketCallback callback) {
		this.callback = callback;
	}
	public String getAddress() {
		if(socket == null)
			return "";
		return socket.getInetAddress().getHostAddress();
	}

	public void accept(Socket socket, Thread parent) {
		close();
		_stop = false;
		this.socket = socket;
		this.parent = parent;
	}
	public void connect(String addr, int port) {
		close();
		_stop = false;
		this.addr = addr;
		this.port = port;
	}
	public void close() {
		_stop = true;
		//interrupt();
		try {
			join();
		}
		catch (InterruptedException e) {
		}
		port = 0; //maybe mistake in mac because of join
		socket = null;
		parent = null;
	}

	public void send(byte[] data, int len) {
		//synchronized (ClientSocketThread.class) {
		try {
			socket.getOutputStream().write(data, 0, len);
			socket.getOutputStream().flush();

			// 由系统标准输入输出设备构造BufferedReader,PrintWriter对象
			// BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
			// PrintWriter sysout = new PrintWriter(System.out);

			// 由Socket对象得到输出流构造BufferedReader,PrintWriter对象
			// BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			// PrintWriter out = new PrintWriter(client.getOutputStream());

			//PrintWriter out = new PrintWriter(client.getOutputStream());
			//out.println(data);
			//out.flush();
		}
		catch (IOException e) {
		}
		//}
	}

	public void run() {
		try {
			if(socket == null) { //for connect
				socket = new Socket(addr, port);
				if(callback != null)
					callback.onConnect(this, socket != null ? 0 : -1);
				System.out.println("client.connect()-------------------");
			}

			/*************************************
			fd_set fdread;
			timeval timeout;
			timeout.tv_sec = 1;
			timeout.tv_usec = 0;
			
			while(true) {
				FD_ZERO(&fdread);
				FD_SET(client, &fdread);
				
				if(select(0, &fdread, 0, 0, &timeout) > 0 && FD_ISSET(client, &fdread)) {
					char buf[1024];
					recv(client, buf, 1024, 0);
				}
			}
			*************************************/

			socket.setSoTimeout(1000);
			byte[] buf = new byte[1048776]; //1024 * 1024 + 200
			//Arrays.fill(buf, (byte) 0);
			while (!_stop && !socket.isClosed()) {
				try {
					//synchronized (ClientSocketThread.class) {
					int len = socket.getInputStream().read(buf, 0, buf.length);
					if(len == -1)
						break;
					if(callback != null)
						callback.onReceive(this, this, buf, len);
					else if(parent != null)
						((ServerSocketThread)parent).doReceive(this, buf, len);
					//}
				}
				catch (SocketTimeoutException e) {
				}
			}
			socket.close();
			if(callback != null)
				callback.onClose(this, socket != null ? 0 : -1);
			else if(parent != null)
				((ServerSocketThread)parent).doClose(this, 0);
			System.out.println("client.close()-------------------");
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}

               //client端:
		thread = new ClientSocketThread();
		thread.connect(addr, port);
		thread.setCallback(this);
		thread.start();

                //server端
		thread = new ServerSocketThread();
		thread.bind(port);
		thread.setCallback(this);
		thread.start();
szuzsq 2014-11-14
  • 打赏
  • 举报
回复
楼主,java最牛逼哄哄的设计模式呢?你是不是应该将通信的底层从界面里面抽出来啊?
生如夏花cch 2014-11-13
  • 打赏
  • 举报
回复
粗略看了一下你的代码,网络操作最好放在线程里,你按钮单机就对Socket读写(也就是说在ui线程里操作了),在Android4.0以上是不能执行的,把他们放在线程中吧,不过这就要考虑线程里怎么更新ui了,很久没写Android了,应该是这样的,你试一下!
生如夏花cch 2014-11-13
  • 打赏
  • 举报
回复
我做个类似的,不过是C#web的,在PC发布web,web也就一个.ashx文件,发送请求,接收数据,处理数据,返回数据就行了,很好学,我当时也是临时学的。后面我学习一下了Java web 的servlet,应该也是可以,如果是短链接,感觉用web比较好操作。
Birds2018 2014-11-13
  • 打赏
  • 举报
回复
如果是短连接 就容易了,服务器端发送数据给客户端后 关闭连接 这样 客户端就能读到流结束。 int count = -1; ByteArrayOutputStream ous = new ByteArrayOutputStream(); while ((count = br.read(buffer) )!= -1) { ous.write(buffer); } byte[] data = ous.toByteArray(); //发送数据给Activity
Birds2018 2014-11-13
  • 打赏
  • 举报
回复
我建议你在 发送数据后启动ReceiveThread 确保你的Socket连接已经成功,考虑网络连接可能有延时。 bw.flush();下面发送后,开始尝试接收数据。 if((count=br.read(buffer))>0) { break; } 这个地方你写读取数据到buffer ,可能无法跳出去, 你这样写 if((count=br.read(buffer))>0) { break; //break 直接启动Activity, 试试。 }

80,337

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧