所谓的Socket通常称为套接字,用于描述IP地址和端口,是一个通信连的句柄。应用程序通过套接字向网络发送请求,或者应答网络请求。Socket套接字,其实就是Java对TCP/IP的实现,Socket和ServerSocket可以形象的比喻为插头和插座,ServerSocket插座提供电源,是服务端;Socket插头要得到电源,是客户端。Socket网络通讯传输数据的过程就好比插头获取插座电源的过程。
服务端:利用ServerSocket监听指定的端口,等待客户端的连接请求,客户端建立连接之后,产生会话,完成会话后,关闭连接。
客户端:利用Socket向网络上的某一个端口发出连接请求,一旦连接成功,产生会话,完成回话之后,关闭连接。
服务器端:
package com.test.server;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketImpl;
import com.sun.imageio.spi.InputStreamImageInputStreamSpi;
/**
* 构建服务器端
*
* @author sjm
*
*
*/
public class Test implements Runnable {
public static final String SERVERIP = "";// ip
public static final int SERVERPORT = 8085;// 端口号
@Override
public void run() {
try {
System.out.println("开始了,小伙~~~~");
ServerSocket socket = new ServerSocket(SERVERPORT);
while (true) {
Socket client = socket.accept();// 等待客户端接入,返回socket对象
System.out.println("等待客户端接入");
try {
// 接收客户端消息
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
// 返回给客户端消息
PrintWriter out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
System.out.println("上面规定好接收和发送~~~~");
String str = in.readLine();// 开始读取客户端的消息
System.out.println("客户端发来的消息是什么呢 ======" + str);
// 设置返回信息
if (str != null) {
out.println("嗨,服务器接收到消息了,你是不是发送了:" + str + "?");
out.flush();
// 将客户端发送的消息保存到本地文件中
File file = new File("e://text.txt");
FileOutputStream fileOut = new FileOutputStream(file);
byte[] bytes = str.getBytes();
for (int i = 0; i < bytes.length; i++) {
fileOut.write(bytes[i]);
}
System.out.println("收到的消息是:" + str);
} else {
System.out.println("收到的消息为空");
}
} catch (Exception e) {
System.out.println("BufferedReader & PrintWriter error");
e.printStackTrace();
} finally {
client.close();
System.out.println("关闭连接,结束~~~~~~~~~~~");
}
}
} catch (Exception e) {
System.out.println("出错了");
e.printStackTrace();
}
}
/**
* 开启服务器
*
* @param args
*/
public static void main(String[] args) {
new Thread(new Test()).start();
}
}
客户端:
package com.example.client;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import org.xml.sax.InputSource;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import junit.framework.Protectable;
public class MainActivity extends ActionBarActivity {
private static final String TAG = "com.example.client.MainActivity";
private Button btn = null;
private TextView tv = null;
private EditText edit = null;
private static final String PORT = "192.168.1.100";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
tv = (TextView) findViewById(R.id.tv);
edit = (EditText) findViewById(R.id.edit);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 开启子线程来进行ui线程的更新,不能在主线程中更新ui
// 当在主线程中更新ui时,1、如果加上finally,会包空指针;2、如果不加,会报NetworkOnMainThreadException异常(网络请求在主线程中异常)
new Thread(networkTask).start();//
}
});
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 接收handler中的消息
Bundle data = msg.getData();
String val = data.getString("value");
Log.i(TAG, "请求结果为-->" + val);
// TODO :UI界面的更新等相关操作
setTitle("测试socket连接");
tv.setText(val);
edit.setText("");// 清空文本框
}
};
/**
* 网络操作相关的子线程
*/
Runnable networkTask = new Runnable() {
@Override
public void run() {
// 开启一个子线程,进行网络操作,等待有返回结果,使用handler通知UI
Socket socket = null;
try {
// InetAddress address = InetAddress.getByName(PORT);//
// 主机地址:服务器ip
socket = new Socket(PORT, 8085);
System.out.println("4");
Log.e(TAG, "连接通了,主机地址为:" + PORT);
// 通过PrintWriter 将消息发送到服务器
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),
true);
// 将输入框内容发送到服务器
String content = edit.getText().toString();
Log.e(TAG, "edit的内容:" + content);
out.println(content);
out.flush();
// 接收服务器消息
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 读取服务器消息
String msg = in.readLine();
// 显示服务器消息到android界面
Message msg1 = new Message();
Bundle data = new Bundle();
data.putString("value", msg);
msg1.setData(data);
handler.sendMessage(msg1);
} catch (UnknownHostException e) {
Log.e(TAG, PORT + "服务器ip错误~~~");
} catch (IOException e) {
Log.e(TAG, "网络连接出错,当前服务器ip为:" + PORT);
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "ssss11111");
e.printStackTrace();
}
}
}
};
}
有一个bug,服务器显示在android界面上的是乱码的,这个很好改的,不想改了~~~~