之前在前面已经介绍了Socket通信的一些基本原理,以及如何让客户端与服务器端建立通信,和实现通信的一些基本步骤(包括首先使得服务器端与客户端建立连接,建立连接之后,服务器端开始侦听客户端的请求,侦听到客户端的请求之后,通过输入输出流处理相关信息实现通信,最后通信完毕结束通信等一系列流程)。
但是之前只是单个客户端与服务器进行通信,而我们实际应用中单个客户端的情况几乎不存在,都是多个客户端同时与服务器进行交互(这里同时交互就会出现并发性的问题,对于并发性的问题暂时还不是很懂,只知道有这个概念),那就需要服务器端不停的侦听客户端的请求(写在while循环中,并且条件始终为true,死循环),每当侦听到一个客户端的请求时,都需要创建一个Socket与之建立通信(通过线程实现,每当侦听到一个客户端的请求,服务端都要单独开辟一条线程与之进行通信)。
下面直接贴代码吧:
1、服务端Socket,(这里面通过死循环让服务器端一直循环侦听来自客户端的请求)
需要注意的是,服务端必须要先于客户端启动,因为要启动之后才能侦听客户端的请求
package com.socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器端Socket
* @author feizi
* @time 2014-11-14下午5:08:16
*/
public class ServerSocketMany {
/**
* main测试方法
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException{
System.out.println("服务器已经启动,等待客户端的连接....");
//创建服务器端Socket,即ServerSOcket,等待客户端的请求
ServerSocket server = new ServerSocket(5555);
int count = 0;//侦听到的客户端的数量
Socket socket = null;//服务器端Socket
//死循环,让服务端循环侦听
while(true){
//服务端开始侦听客户端的连接
socket = server.accept();
//启动线程,与客户端进行通信
Thread serverThread = new ServerThread(socket);
serverThread.start();
//计数,统计客户端连接数
count++;
System.out.println("当前链接的客户端的数量为:"+count+"个....");
}
}
}
package com.socket;
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;
/**
* 创建一个服务端线程,循环侦听客户端的请求,多个客户端
* @author feizi
* @time 2014-11-14下午5:36:45
*/
public class ServerThread extends Thread{
//每当侦听到一个新的客户端的时,服务端这边都要有一个Socket与之进行通信
public Socket socket = null;
//默认的构造方法,保留
public ServerThread(){}
//带参构造方法
public ServerThread(Socket socket){
this.socket = socket;
}
//覆写run方法
public void run(){
//获取输入字节流
InputStream in = null;
//将输入字节流包装成输入字符流
InputStreamReader isr = null;
//为字符输入流添加缓冲
BufferedReader br = null;
//收到信息之后,向客户端响应信息,获取输出字节流
OutputStream out = null;
//将字节输出流包装成字符打印输出流
PrintWriter pw = null;
try {
in = socket.getInputStream();
isr = new InputStreamReader(in);
br = new BufferedReader(isr);
//读取字符输入流中的数据
String data = null;
while((data = br.readLine()) != null){
System.out.println("我是服务器,客户端说:"+data);
}
//调用shutDown方法关闭Socket输入流
socket.shutdownInput();
out = socket.getOutputStream();
pw = new PrintWriter(out);
pw.write("用户名和密码正确");
pw.flush();
//调用shutDown方法关闭Socket输出流
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}finally{
//关闭资源
try {
if(null != pw)
pw.close();
if(null != out)
out.close();
if(null != br)
br.close();
if(null != isr)
isr.close();
if(null != in)
in.close();
if(null != socket)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
3、客户端Socket,这个和单客户端的情况一样,在第一篇中有详细介绍
package com.socket;
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;
/**
* 客户端Socket
* @author feizi
* @time 2014-11-14下午5:18:06
*/
public class ClientSocketDemo {
/**
* main测试方法
* @param args
* @throws UnknownHostException
* @throws IOException
*/
public static void main(String[] args) throws UnknownHostException, IOException{
//创建客户端Socket,向服务器发起请求
// String address = "127.0.0.1";
String address = "localhost";//服务器地址
int port = 5555;//端口号
Socket socket = new Socket(address, port);
//获取Socket的字节输出流
OutputStream out = socket.getOutputStream();
//将字节输出流包装成字符打印输出流
PrintWriter pw = new PrintWriter(out);
// pw.print("用户名:admin,密码:123");
// pw.print("用户名:tom,密码:456");
// pw.print("用户名:dark,密码:789");
// pw.print("用户名:white,密码:111");
pw.print("用户名:green,密码:222");
//刷新输出流
pw.flush();
//调用shutDown方法关闭Socket的输出流
socket.shutdownOutput();
//接收服务器端发来的响应信息,获取字节输入流
InputStream in = socket.getInputStream();
//将字节输入流包装成字符输入流
InputStreamReader isr = new InputStreamReader(in);
//为字符输入流添加缓冲
BufferedReader br = new BufferedReader(isr);
//读取字符输入流中的数据信息
String data = null;
while((data = br.readLine()) != null){
System.out.println("我是客户端,服务器说:"+data);
}
//调用shutDown方法关闭Socket的输入流
socket.shutdownInput();
br.close();
isr.close();
in.close();
pw.close();
out.close();
socket.close();
}
}
下面是程序运行结果截图:
客户端:
服务器端:
大家可以点此链接查看单客户端与服务器端交互的情况:
每天成长一点点,始终坚信:天道酬勤,努力了,奋斗了,一切切有可能!