首先写一个ServerSocket(服务器端的监听类)用于监听Socket连接,每新产生一个对话,都交由Socket的实例去处理.
package com.pan.socket.service;
import javax.net.ServerSocketFactory;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by pan on 2016/10/4.
*/
public class MyServer extends Thread {
public void run() {
try {
//创建serverSocket,并绑定端口.
ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(2354);
System.out.println("服务启动成功,正在监听端口2354");
//接受客户端请求
while (true) {
Socket accept = serverSocket.accept();
//每新增一个对话,交给一个Socket的实例去处理
new MySocket(accept).start();
System.out.println("客户端已经连接...");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后,编写Socket服务端实例,用于与客户端的通信
package com.pan.socket.service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* Created by pan on 2016/10/4.
*/
public class MySocket extends Thread {
private Socket socket;
//实例化传入socket对象
public MySocket(Socket socket) {
this.socket = socket;
}
public void run() {
//像客户端输出提示信息
write("已经连接..");
//读取客户端的输入
reader();
}
/**
* 读取客户端输入的数据
*/
private void reader() {
try {
//接受客户端数据
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"), MAX_PRIORITY);
String line;
//循环读取客户端的数据
while ((line = reader.readLine()) != null) {
//退出指令
if (!line.equalsIgnoreCase("exit")) {
System.out.println("客户端输入:" + line);
//向客户端写入
write(line);
} else {
write("正在退出...");
System.out.println("一个客户端退出");
break;
}
}
//关闭流
reader.close();
} catch (IOException e) {
System.out.println("失去响应");
}
}
/**
* 向客户端写入数据
*/
void write(String str) {
try {
socket.getOutputStream().write((str + "\n").getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后是启动服务端的类,用于启动服务.
package com.pan.socket.service;
/**
* Created by pan on 2016/10/4.
*/
public class Main {
public static void main(String[] args) {
new MyServer().start();
}
}
第二部分:客户端代码
客户端首先需要新建一个类,用于连接服务端.并接受服务端信息,以及向服务端发送消息.客户端不需要监听Socket,所以相比于服务端要少一个监听的类.
连接服务端并执行信息处理类
package com.pan.socket.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Scanner;
/**
* Created by pan on 2016/10/4.
*/
public class ClientSocket extends Thread {
private Socket socket;
public void run() {
try {
socket = new Socket("127.0.0.1", 2354);
new Thread() {
public void run() {
//接受用户输入
Scanner scanner = new Scanner(System.in);
String inStr;
while ((inStr = scanner.nextLine()) != null) {
write(inStr);
//退出指令
if (inStr.equalsIgnoreCase("exit")) {
System.out.println("客户端退出");
break;
}
}
//输入流关闭
scanner.close();
}
}.start();
//读取服务端消息
reader();
} catch (IOException e) {
System.out.println("连接失败");
}
}
/**
* 读取服务端数据
*/
private void reader() {
try {
//接受客户端数据
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"), MAX_PRIORITY);
String line;
//循环读取服务端的数据
while ((line = reader.readLine()) != null) {
System.out.println("服务端:" + line);
}
//关闭流
reader.close();
} catch (IOException e) {
System.out.println("失去响应");
}
}
/**
* 向服务端些数据
*/
void write(String str) {
try {
socket.getOutputStream().write((str + "\n").getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
ps:这里采用控制台输入,因为两个死循环,所以采用new Thread(){} ;新建一个线程去处理循环监听控制台输入,主线程循环监听服务端数据.
2.启动客户端类
package com.pan.socket.client;
/**
* Created by pan on 2016/10/4.
*/
public class Main {
public static void main(String[] args) {
new ClientSocket().start();
}
}
3.测试:
启动服务端,然后在启动客户端,输入一些数据.
4.结果
服务端:
服务启动成功,正在监听端口2354
客户端已经连接...
客户端输入:88
客户端输入:萨大幅
客户端输入:sa
一个客户端退出
客户端:
服务端:已经连接..
88
服务端:88
萨大幅
服务端:萨大幅
sa
服务端:sa
exit
客户端退出
服务端:正在退出...
Process finished with exit code 0
题外:
如果需要通知功能,那么服务端添加一个用于管理MySocket的类,在该类下来实现MySocket对象的存储,以及遍历实现通知功能.