“一切皆Socket!”
话虽些许夸张,但是事实也是,现在的网络编程几乎都是用的socket。
——有感于实际编程和开源项目研究。
Socket是网络通信的一种方式,它的原理和详解,作为一个职场小白,我也了解得不是很透彻,在这里就不妄加论述了,只是说说socket最基本的用法。
首先是服务端:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import android.util.Log;
/**
* Socket通信的工具类(服务端)
* Created by 禽兽先生
* Created on 2016.03.06
*/
public class Server {
private static Server server;
private static ServerSocket mServerSocket;
private Socket socket;
/* 服务器端口 */
private final static int SERVER_HOST_PORT = 服务器端口号;
/**
* 单例模式
*/
public static Server getInstance() {
if (server == null) {
server = new Server();
}
return server;
}
/**
* 打开Socket通道,等待客户端连接
*/
private static ServerSocket getServerSocket() {
if (mServerSocket == null) {
try {
mServerSocket = new ServerSocket(SERVER_HOST_PORT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return mServerSocket;
}
/**
* 打开Socket通道,循环等待客户端连接
*/
public void connect() {
// TODO Auto-generated method stub
try {
mServerSocket = getServerSocket();
Log.i("daolema", "socket已开启,等待连接");
while (true) {
socket = mServerSocket.accept();
if (socket.isConnected()) {
Log.i("daolema", "socket连接成功");
break;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 断开Socket连接
*/
public void disconnect() {
// TODO Auto-generated method stub
try {
if (socket != null && socket.isConnected()) {
socket.close();
mServerSocket.close();
Log.i("daolema", "socket断开了");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 读取固定长度的流,返回byte[]
*/
public byte[] read() {
try {
if (!socket.isConnected()) {
socket = mServerSocket.accept();
}
InputStream is = socket.getInputStream();
return readBytes(is, 4);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 读取指定长度的流,返回byte[]
*/
public byte[] read(int length) {
// TODO Auto-generated method stub
try {
if (!socket.isConnected()) {
socket = mServerSocket.accept();
}
InputStream is = socket.getInputStream();
return readBytes(is, length);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 从socket读byte数组
* @param in
* @param length
* @return
*/
public static byte[] readBytes(InputStream in, long length) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read = 0;
while (read < length) {
int cur = 0;
try {
cur = in.read(buffer, 0, (int) Math.min(1024, length - read));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (cur < 0) {
break;
}
read += cur;
baos.write(buffer, 0, cur);
}
return baos.toByteArray();
}
}
客户端:
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import android.util.Log;
/**
* Socket通信的工具类(客户端)
* Created by 禽兽先生
* Created on 2016.03.06
*/
public class Client {
private static Client mClient;
private static Socket mSocket;
// 要连接的服务器IP地址
private static final String HOST_ADDRESS = 服务器IP地址;
// 要连接的服务器端口号
private static final int HOST_PORT = 服务器端口号;
/**
* 单例模式
*/
public static Client getInstance() {
if (mClient == null) {
mClient = new Client();
}
return mClient;
}
/**
* 打开Socket通道,连接服务器
*/
private static Socket getSocket() {
if (mSocket == null) {
try {
mSocket = new Socket(HOST_ADDRESS, HOST_PORT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return mSocket;
}
/**
* 打开Socket通道,连接服务器
*/
public void connect() {
// TODO Auto-generated method stub
mSocket = getSocket();
Log.i("daolema", "socket成功连接");
}
/**
* 断开Socket连接
*/
public void disconnect() {
if (mSocket != null && mSocket.isConnected()) {
try {
mSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 发送byte[]
*/
public void send(byte[] bytes) {
try {
if (!mSocket.isConnected()) {
mSocket = getSocket();
}
OutputStream os = mSocket.getOutputStream();
os.write(bytes);
os.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
需要注意的一点是Socket只能创建一次,保证只有一条通道。这两个类中,传递的数据都是byte[]类型的,传输文件当然是byte[]这个没问题,然后在java中,String也有getBytes[]方法可以转换为byte[],但是其他,比如int类型的数据就需要我们自己转换了,这里面有int和byte[]互转的方法。
http://blog.csdn.net/zgcqflqinhao/article/details/53256862
这里介绍的只是Socket最基本的用法,建立最基本的Socket通信,传递byte[]类型数据,作为我自己的工具类,如有更多需要,要扩展起来也很方便