Java socket 基于TCP/IP 协议应用
多线程服务器原理:
1、 服务器端创建serversocket并绑定要监听的端口号 ,循环调用serversoket 的accept()方法,等待客户端的连接请求
2、 客户端创建一个socket绑定服务器端的IP地址和服务器监听的端口号并请求和服务器端连接
3、 服务器端接收到客户端的请求后,创建一个socket与客户端建立专线连接
4、 建立连接的两个socket在一个单独的线程上对话
5、 服务器端继续等待新的连接
socket.shutdownOutput();和socket.shutdownInput() 注意区分
注意:客户端向服务器端传送数据的时候大多时候将数据封装成一个对象,而不是本文中使用的字符串
Socket socket = new Socket( "localhost",8888);
OutputStream os =
socket.getOutputStream();
//使用ObjectOutputStream 对象序列化流,传递对象
ObjectOutputStream
objectOutputStream =new ObjectOutputStream(os);
User user = new User("最帅的","123");//将数据封装为user对象
//序列化
objectOutputStream.writeObject(user);
socket.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = br.readLine();
while(info != null){
System.out.println("这里是客户端,服务器传来消息:"+info);
info =br.readLine();
传递文件
objectInputStream
clientInputStream = null;
//下载后首先生成一个临时文件
String fileNaemTemp
= "temp.txt";
String downloadPath =
ConfigManager.getInstance(0.getString(Constants.CLIENT_DOWNLOAD_PA
try{
clientInputStream = new ObjectInputStream(clientSocket.getInputStream());
File fileTemp = new File(downloadPath +
"/"+fileNaemTemp);
if(fileTemp.exists()){
fileTemp.delete();
}
fileTemp.createNewFile();
BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(new FileOutputStream(fileTemp));
//接受服务器的文件
byte []
buf = new byte[1024];
int len;
while((len= clientInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
bufferedOutputStream.flush();
客户端:
import java.net.Socket;
/**
* @描述:客户端
* Created by Jim Calark on 2017/3/17.
*/
public class Client {
public static void main(String[]
args) {
try {
//创建客户端socket,指定服务器IP地址和端口号
Socket
socket = new Socket("localhost",65533);
//获取socket 输出流
OutputStream os =socket.getOutputStream();
/将字节输出流转为打印流
PrintWriter pw = new PrintWriter(os);
//输出到服务器端
pw.write("你好,我是客户端");
//冲流
pw.flush();
//pw.close()//这里不能关闭输出流,会导致socket也会关闭;关闭socke
//的时候会自动关闭该socket下的输出流
//关闭输出流
关错了,关到输入流了 告诉服务器端消息发送完毕
//不关闭该输出流的情况下,会一直卡在线程中读取数据那里
socket.shutdownOutput();
//获取 socket输入流,读取服务器端响应信息
InputStream is =socket.getInputStream();
//将字节流转换为字符流,提高读取效率
InputStreamReader isr = new InputStreamReader(is);
//为字符流设立缓冲区
BufferedReader br = new BufferedReader(isr);
String data = null;
//循环读取数据
while((data = br.readLine()) != null){
System.out.println(data);
}
//关闭资源
is.close();
isr.close();
br.close();
pw.close();
socket.close();
} catch
(IOException e) {
e.printStackTrace();
}
}
}
通信线程类
import java.io.*; import java.net.Socket; /** * @描述:线程服务类 * Created by Jim Calark on 2017/3/17. */ public class ServerThread extends Thread{ /** 和本线程有关的socket */ Socket socket = null; //以socket 为参数的构造器 public ServerThread (Socket socket){ this.socket = socket; } //线程执行的操作,响应客户的请求 public void run(){ InputStream is = null; OutputStream os = null; BufferedReader br = null; InputStreamReader isr = null; PrintWriter pw = null; try { //获取socket中客户端请求的字节输入流 is = socket.getInputStream(); //将字节输入流转为字符输入流 isr = new InputStreamReader(is); //建立缓冲区,提高数据读取效率 br = new BufferedReader(isr); String data = null ; //循环读取数据,每次读取一行 while((data = br.readLine())!= null){ //打印数据 System.out.println("客户端传来的消息"+data); }
socket.shutdownInput();//关闭输入流 //获取输出流响应客户端请求 os = socket.getOutputStream(); pw = new PrintWriter(os); pw.write("欢迎连接服务器端!"); pw.flush();//调用flush()方法将缓冲输出 } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 try{ if(is !=null){ is.close(); } if(isr != null){ isr.close(); } if(br != null){ br. close(); } if ( os != null){ os.close(); } if(pw != null){ pw.close(); } if(socket != null){ socket.close(); } }catch (IOException e){ e.printStackTrace(); } } }
服务器端
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * @描述:服务器端类 * Created by Jim Calark on 2017/3/17. */ public class Server { public static void main(String[] args) { try { //创建一个服务器端ServerSocket类,绑定要监听的端口号 ServerSocket serverSocket = new ServerSocket(65533); Socket socket = null; //记录客户端连接的数量 int count = 0; System.out.println("**********服务器即将启动,等待客户端的连接********************"); //循环监听等待客户端的连接 while(true){ //调用ServerSocket 的accept() 开始方法监听,等待客户端的连接,一旦连接就创建一个服务器端的Socket socket = serverSocket.accept(); //为一个新的连接创建一个新线程 ServerThread serverThread = new ServerThread(socket);
//设置线程的优先级,范围为[1,10],默认为5。未设置优先级可能会导致运行时速度
//非常慢,可降低优先级
serverThread.setPriority(4); //启动线程 serverThread.start(); count++; System.out.println("当前共"+count + "个客户端连接"); } } catch (IOException e) { e.printStackTrace(); } } }