您的位置:首页 > 理论基础 > 计算机网络

Android学习笔记(30) --- 网络通信之Socket简单使用

2012-10-18 16:49 363 查看
关于Socket,百度百科是这么说的:

什么是socket

  所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。以J2SDK-1.3为例,Socket和ServerSocket类库位于java .net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。

重要的Socket API

  重要的Socket API:java .net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。  1、Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。  2、getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。  3、getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。注意:其中getInputStream和getOutputStream方法均可能会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。

SOCKET连接过程

  根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。  

服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。  

客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址端口号,然后就向服务器端套接字提出连接请求。  

连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

下面以一个服务器和客户端例子说明Socket的使用:

1、服务器端:

创建步骤:

1.1、指定端口实例化一个ServerSocket

1.2、调用ServerSocket的accept()在等待连续期间造成阻塞

1.3、获取底层Socket的流进行读写操作

1.4、将数据库封装成流

1.5、对Socket进行读写

1.6、关闭打开的流和Socket

服务端代码如下:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			ServerSocket serverSocket = new ServerSocket(54323);
			while (true) {
				Socket client = serverSocket.accept();
				try {
					BufferedReader read = new BufferedReader(
							new InputStreamReader(client.getInputStream()));
					String str = read.readLine();
					System.out.println("read-->" + str);

					PrintWriter write = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(client.getOutputStream())),
							true);
					write.println("server message");
					
					read.close();
					write.close();
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
					e.printStackTrace();
				}
				finally{
					client.close();
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e.getMessage());
		}
	}
	public static void  main(String a[]) {
		Thread ServerThread = new Thread(new Server());
		ServerThread.start();
	}

}


2、客户端

创建步骤:

2.1、通过IP地址和端口实例化Socket,请求连接服务器

2.2、获取Socket上的流进行读写

2.3、把数据流包装进BufferedReader/PrintWriter的实例

2.4、对Socket进行读写操作

2.5、关闭打开的流于Socket

客户端代码如下(xml文件就不再给出了):

package com.ideal.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Net_SocketClientActivity extends Activity {
	private TextView mTextView = null;

	private EditText mEditText = null;

	private Button mButton = null;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mButton = (Button) findViewById(R.id.Button01);

		mTextView = (TextView) findViewById(R.id.TextView01);

		mEditText = (EditText) findViewById(R.id.EditText01);

		mButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) { 
				// TODO Auto-generated method stub
				Socket socket = null;
				String message = mEditText.getText().toString() + "\r\n";
				try {
					socket = new Socket("172.31.100.50", 54323);

					PrintWriter write = new PrintWriter(new BufferedWriter(
							new OutputStreamWriter(socket.getOutputStream())),
							true);
					write.println(message);

					BufferedReader read = new BufferedReader(
							new InputStreamReader(socket.getInputStream()));
					String msg = read.readLine();
					if(msg!=null){
						mTextView.setText(msg);
					}else {
						mTextView.setText("error");
					}
					write.close();
					read.close();
					socket.close();
				} catch (Exception e) {
					// TODO: handle exception
					System.out.println(e.getMessage());
				}
			}
		});
	}
}


3、针对上面的客户端与服务器端,需要注意的地方

3.1、服务器端和客户端在同一个局域网才能使用

3.2、

socket = new Socket("172.31.100.50", 54323);


上面的ip地址并非Internet IP ,我是使用了下面的IPv4 地址:



另,会出现端口问题,如果你的端口(如上面的54323)被占用了,那么会出现如下情况:



解决方法:

一:更改服务器的端口号;

二:关闭占用当前端口的进程

下边介绍第二种方法

1.首先进入命令行
查看端口是否被占用

使用命令:
netstat -ano



2.查看该PID为
54323 的进程

使用命令:tasklist|findstr
"54323"

然后可直接退出该进程,或者到任务管理器关闭掉该进程。

4、看下正常运行的结果:

客户端:



服务器端:

eclipse中Console窗口查看



CMD命令窗口查看

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: