一个简单的Android的利用socket通信,为什么连服务器的时候要点两下才能连上(附代码),求大神指点

九帝十皇 发布于 2013/08/07 12:38
阅读 650
收藏 1
问题是安卓客户端界面的按钮,要按两下才能连接上服务器查出数据,我是个新手,请大家指教...
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import Thread.selectThread;
import Thread.selectThread2;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

	private TextView text1= null;
	private Socket s;
	private Button but = null;
	private Handler handler;
	
	 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		this.text1 = (TextView) super.findViewById(R.id.text1);
		this.but = (Button) super.findViewById(R.id.but1);
		this.but.setOnClickListener(new OnClickListenerImpl());      // 添加监听
				
		handler = new Handler(){

			@Override
			public void handleMessage(Message msg) {
				
				String message = (String) msg.obj;               //获取handler的参数值
				MainActivity.this.text1.setText(message);
				;
			}
			
		};
		

	}
	
	
	

	
	private class OnClickListenerImpl implements OnClickListener{

		@Override
		public void onClick(View arg0) {
			
			selectThread sThread = new selectThread(s,handler);
			Thread t = new Thread(sThread);
			t.start();
			
			
			System.out.println("监听开启");

		}
	
	}
	}

下面是线程代码

package Thread;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Handler;
import android.os.Message;

public class selectThread implements Runnable{
	private Socket s;
	private Handler handler;
	
	public selectThread(Socket s,Handler handler){
		this.s = s;
		this.handler = handler;
	}
	
	@Override
	public void run() {
		System.out.println("线程开启");
		String str  = "null";
		String name = "刘同乐";
		try {
			s = new Socket("192.168.1.100",9091);
			DataOutputStream dos = new DataOutputStream(s.getOutputStream());
			DataInputStream dis = new DataInputStream(s.getInputStream());
			dos.writeUTF(name);
			str = dis.readUTF();
			Message msg = new Message();
			msg.obj = str;
			handler.sendMessage(msg);

		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	 
	}	
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 >

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
	
    <Button
        android:id="@+id/but1"
        android:text="查询数据库"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
   
</LinearLayout>
AndroidManifest.xml

中也配置了<uses-permission android:name="android.permission.INTERNET"/>

 

 

最后是服务器代码

import java.net.ServerSocket;
import java.net.Socket;

import service.ClientServiceThread;

public class server {
	public static void main(String[] args) {
		try{
			while(true){
				ServerSocket server = new ServerSocket(9091);
				
				Socket s = server.accept();
				Socket sends = server.accept();
				ClientServiceThread cst = new ClientServiceThread(s,sends);
				
				Thread t = new Thread(cst);
//				StrictMode
//						.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
//								.detectDiskReads().detectDiskWrites()
//								.detectNetwork().penaltyLog().build());
				t.start();
				System.out.println("A client is connected");
				server.close();
				
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import UserDao.UserDao;

public class ClientServiceThread implements Runnable{

	private Socket s;
	private Socket sends;
	
	
	public ClientServiceThread(Socket s,Socket sends){
		this.s = s;
		this.sends = sends;
	}

	@Override
	public void run() {
		String str = null;
		try {
			DataOutputStream dos = new DataOutputStream(s.getOutputStream());
			DataInputStream dis = new DataInputStream(s.getInputStream());
			while(true){
				str = dis.readUTF();
				UserDao ud = new UserDao();
				String message  = ud.getMesssge(str);
				dos.writeUTF(message);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}

 

 

 

加载中
0
BladeBao
BladeBao

服务端,这个写法是错误的。

Socket s = server.accept();

Socket sends = server.accept();

问题的原因是这样的,ServerSocket accpet方法返回与客户端peer对应的本地套接字描述符,accept以后就是双向的,可以收也可以发,没必要写两个。accept方法是阻塞的,一个客户端conect只能让一个accept函数返回,所以你第一点击,第一个accept返回,但是又阻塞到第二个accept中去了,第二次点击,服务的线程才能继续往下执行。把第二个accept删掉就好了。建议你去学习一下基本的套接字用法

九帝十皇
九帝十皇
长姿势了,多谢指点...
返回顶部
顶部