首先介绍一下用Socket(套接字)实现服务器端和客户端的通信过程
服务器端:
1、创建ServerSocket对象,绑定监听端口
2、通过accept()方法监听客户端请求
3、连接建立后,通过输入流读取客户端发送的请求信息
4、通过输出流向客户端发送相应信息
5、关闭相应资源
客户端:
1、创建Socket对象,指明需要连接的服务器的地址和端口号
2、连接建立后,通过输出流向服务器端发送请求信息
3、通过输入流获取服务器响应的信息
4、关闭相关资源
在服务器端,首先可以用ServerSocket类来初始化一个对象,指定一个特定的端口号作为监听端口
在这里我使用第二个构造方法。ServerSocket的实例对象可以调用.accept()方法来获取Socket的实例对象,由于实际情况是有很多个客户端发出指向服务器端的请求,为了实现多级响应,就要用到多线程的技术,为每个客户端的socket创建专门的线程。
应用多线程来实现服务器与多客户端之间的通信
基本步骤:
1、服务器创建ServerSocket,循环调用accept()等待客户端连接
2、客户端创建一个socket并请求和服务器端连接
3、服务器端接受客户端请求,创建socket与该客户建立专线连接
4、建立连接的两个socket在一个单独的线程上对话
5、服务器继续等待新的连接
下面是服务器端的代码实现:
package com.yjp;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 基于TCP协议的Socket通信,实现用户登录
* 服务器端
*/
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("***服务器即将启动,等待客户端的连接***");
Socket socket = null;
int count = 0;
while (true) {
socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
count++;
System.out.println("客户端数量为: " + count);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在上面的代码中用了一个死循环来一直监听本机上的8888端口,一旦有客户端发出请求,就创建Thread(线程类)的子类来实现具体的通信。
下面是线程类ServerThread的实现代码:
package com.yjp;
/*
* 服务器线程处理类
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread {
//与本线程相关的socket
Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
//线程执行的相关操作,响应客户端的请求
public void run() {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
//获取输出流,响应客户端请求
OutputStream outputStream = null;
PrintWriter printWriter = null;
try {
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
String string = null;
while ((string = bufferedReader.readLine()) != null) {
System.out.println("我是服务器,客户端说: " + string);
}
socket.shutdownInput();
outputStream = socket.getOutputStream();
printWriter = new PrintWriter(outputStream);
printWriter.write("欢迎您");
printWriter.flush();
socket.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
//关闭资源
printWriter.close();
outputStream.close();
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
下面是客户端的实现代码:
package com.yjp;
/*
* 客户端
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
printWriter.write("用户名:admin;密码:1234");
printWriter.flush();
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String string = null;
while ((string = bufferedReader.readLine()) != null) {
System.out.println("我是客户端,服务器说: " + string);
}
socket.shutdownInput();
//关闭资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
printWriter.close();
outputStream.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
一个基本的流程就是:客户端发出socke请求,创建输出流发送数据—>服务器端监听到有客户端发出请求,创建输入流接收数据—>服务器端处理接收到的数据,创建输出流发送数据响应客户端的请求—>客户端创建输入流接收服务器发送的响应信息。最后就是输入输出流的关闭以及Socket对象的关闭。多线程用到的就是Thread类来为每个特地的Socket生成特定对象,这样就实现了多客户端分别与服务器端通信。