Netty学习之一--Java socket编程(单线程+多线程)
2017-05-11 17:59
357 查看
1. Socket 通信简介及模型
Java Socket 可实现客户端--服务器间的双向实时通信。java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的client和server端。
1.1 重要的Socket API:
Accept方法用于产生”阻塞”,直到接受到一个连接,并且返回一个客户端的Socket对象实例。”阻塞”是一个术语,它使程序运行暂时”停留”在这个地方,直到一个会话产生,然后程序继续
GetInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
GetOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
2. Socket 通信实现方法
2.1 服务器端(单线程)
实例化SeverSocket对象。
调用ServerSocket的accept()方法,生成socket对象,监听从端口上发来的连接请求,等待连接期间会造成阻塞,。
根据生成的客户端的Socket对象,进行读写IO操作。
关闭打开的流和Socket对象。
2.2 客户端
连接客户端指定IP端口,实例化socket对象。
根据生成socket对象,进行读写IO操作。
关闭打开的流和Socket对象。
2.3 服务器端 (多线程)
实例化SeverSocket对象,循环调用accept()等待客户端连接
客户端创建一个socket并请求和服务器端连接
服务器端接受客户端请求,创建socket与该客户建立专线连接
建立连接的两个socket在一个单独的线程上对话
服务器端继续等待新的连接
PS:多线程下服务器发送数据,客户端争抢服务器资源
服务器代码(单线程/单客户端)
import java.io.BufferedReader;
import java.io.IOExc
4000
eption;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
//搭建服务器端
public static void main(String[] args) throws IOException{
SocketService socketService = new SocketService();
//1、a)创建一个服务器端Socket,即SocketService
socketService.oneServer();
}
public void oneServer(){
try{
ServerSocket server=null;
try{
server=new ServerSocket(3900);
//b)指定绑定的端口,并监听此端口。
System.out.println("服务器启动成功");
//创建一个ServerSocket在端口3900监听客户请求
}catch(Exception e) {
System.out.println("没有启动监听:"+e);
//出错,打印出错信息
}
Socket socket=null;
try{
socket=server.accept();
//2、调用accept()方法开始监听,等待客户端的连接
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exception e) {
System.out.println("Error."+e);
//出错,打印出错信息
}
//3、获取输入流,并读取客户端信息
String line;
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter writer=new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+in.readLine());
//在标准输出上打印从客户端读入的字符串
line=br.readLine();
//从标准输入读入一字符串
//4、获取输出流,响应客户端的请求
while(!line.equals("end")){
//如果该字符串为 "bye",则停止循环
writer.println(line);
//向客户端输出该字符串
writer.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+in.readLine());
//从Client读入一字符串,并打印到标准输出上
line=br.readLine();
//从系统标准输入读入一字符串
} //继续循环
//5、关闭资源
writer.close(); //关闭Socket输出流
in.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e) {//出错,打印出错信息
System.out.println("Error."+e);
}
}
}
客户端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
public class SocketClient {
// 搭建客户端
public static void main(String[] args) throws IOException {
try {
// 1、创建客户端Socket,指定服务器地址和端口
Socket socket=new Socket("127.0.0.1",3900);
System.out.println("客户端启动成功");
// 2、获取输出流,向服务器端发送信息
// 向本机的3900端口发出客户请求
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 构造BufferedReader对象
PrintWriter write = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
//3、获取输入流,并读取服务器端的响应信息
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline;
readline = br.readLine(); // 从系统标准输入读入一字符串
while (!readline.equals("end")) {
// 若从标准输入读入的字符串为 "end"则停止循环
write.println(readline);
// 将从系统标准输入读入的字符串输出到Server
write.flush();
// 刷新输出流,使Server马上收到该字符串
System.out.println("Client:" + readline);
// 在系统标准输出上打印读入的字符串
System.out.println("Server:" + in.readLine());
// 从Server读入一字符串,并打印到标准输出上
readline = br.readLine(); // 从系统标准输入读入一字符串
} // 继续循环
//4、关闭资源
write.close(); // 关闭Socket输出流
in.close(); // 关闭Socket输入流
socket.close(); // 关闭Socket
} catch (Exception e) {
System.out.println("can not listen to:" + e);// 出错,打印出错信息
}
}
}
服务器代码(多线程/多客户端)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
// 搭建服务器端
public static void main(String[] args) throws IOException {
SocketService socketService = new SocketService();
// 1、a)创建一个服务器端Socket,即SocketService
socketService.oneServer();
}
public void oneServer() {
try {
ServerSocket server = null;
try {
server = new ServerSocket(3900);
// b)指定绑定的端口,并监听此端口。
System.out.println("服务器启动成功");
// 创建一个ServerSocket在端口3900监听客户请求
} catch (Exception e) {
System.out.println("没有启动监听:" + e);
// 出错,打印出错信息
}
Socket socket = null;
int i = 0;
int count = 100;// 限制最大连接为100
while (i++ < count) {
try {
socket = server.accept();
System.out.println("当前连接数量:" + i);
// 2、调用accept()方法开始监听,等待客户端的连接
// 使用accept()阻塞等待客户请求,有客户
// 请求到来则产生一个Socket对象,并继续执行
Handler handler = new Handler(socket, i);
new Thread(handler).start();
} catch (Exception e) {
System.out.println("Error." + e);
// 出错,打印出错信息
}
}
server.close(); // 关闭ServerSocket
} catch (Exception e) {// 出错,打印出错信息
System.out.println("Error." + e);
}
}
}
class Handler implements Runnable {
private Socket socket;
private int i;
public Handler(Socket socket, int i) {
this.socket = socket;
this.i = i;
}
public void run() {
BufferedReader in = null;
PrintWriter writer = null;
BufferedReader br = null;
try {
// 3、获取输入流,并读取客户端信息
String line;
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
writer = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
br = new BufferedReader(new InputStreamReader(System.in));
// 由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+ i + ":" + in.readLine());
// 在标准输出上打印从客户端读入的字符串
line = br.readLine();
// 从标准输入读入一字符串
// 4、获取输出流,响应客户端的请求
while (!line.equals("end")) {
// 如果该字符串为 "bye",则停止循环
writer.println(line);
// 向客户端输出该字符串
writer.flush();
// 刷新输出流,使Client马上收到该字符串
System.out.println("Server:" + line);
// 在系统标准输出上打印读入的字符串
System.out.println("Client" + i + ":" + in.readLine());
// 从Client读入一字符串,并打印到标准输出上
line = br.readLine();
// 从系统标准输入读入一字符串
} // 继续循环
} catch (Exception e) {
System.out.println("Error." + e);
// 出错,打印出错信息
} finally {
// 5、关闭资源
try {
writer.close(); // 关闭Socket输出流
in.close();
socket.close(); // 关闭Socket
} catch (IOException e) {
System.out.println("Error." + e);
// 出错,打印出错信息
} // 关闭Socket输入流
}
}
}
叁考资料:http://www.cnblogs.com/wisdo/p/5860001.html
http://blog.csdn.net/qq_23473123/article/details/51461894
Java Socket 可实现客户端--服务器间的双向实时通信。java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的client和server端。
1.1 重要的Socket API:
Accept方法用于产生”阻塞”,直到接受到一个连接,并且返回一个客户端的Socket对象实例。”阻塞”是一个术语,它使程序运行暂时”停留”在这个地方,直到一个会话产生,然后程序继续
GetInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
GetOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
2. Socket 通信实现方法
2.1 服务器端(单线程)
实例化SeverSocket对象。
调用ServerSocket的accept()方法,生成socket对象,监听从端口上发来的连接请求,等待连接期间会造成阻塞,。
根据生成的客户端的Socket对象,进行读写IO操作。
关闭打开的流和Socket对象。
2.2 客户端
连接客户端指定IP端口,实例化socket对象。
根据生成socket对象,进行读写IO操作。
关闭打开的流和Socket对象。
2.3 服务器端 (多线程)
实例化SeverSocket对象,循环调用accept()等待客户端连接
客户端创建一个socket并请求和服务器端连接
服务器端接受客户端请求,创建socket与该客户建立专线连接
建立连接的两个socket在一个单独的线程上对话
服务器端继续等待新的连接
PS:多线程下服务器发送数据,客户端争抢服务器资源
服务器代码(单线程/单客户端)
import java.io.BufferedReader;
import java.io.IOExc
4000
eption;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
//搭建服务器端
public static void main(String[] args) throws IOException{
SocketService socketService = new SocketService();
//1、a)创建一个服务器端Socket,即SocketService
socketService.oneServer();
}
public void oneServer(){
try{
ServerSocket server=null;
try{
server=new ServerSocket(3900);
//b)指定绑定的端口,并监听此端口。
System.out.println("服务器启动成功");
//创建一个ServerSocket在端口3900监听客户请求
}catch(Exception e) {
System.out.println("没有启动监听:"+e);
//出错,打印出错信息
}
Socket socket=null;
try{
socket=server.accept();
//2、调用accept()方法开始监听,等待客户端的连接
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exception e) {
System.out.println("Error."+e);
//出错,打印出错信息
}
//3、获取输入流,并读取客户端信息
String line;
BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应的BufferedReader对象
PrintWriter writer=new PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造PrintWriter对象
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+in.readLine());
//在标准输出上打印从客户端读入的字符串
line=br.readLine();
//从标准输入读入一字符串
//4、获取输出流,响应客户端的请求
while(!line.equals("end")){
//如果该字符串为 "bye",则停止循环
writer.println(line);
//向客户端输出该字符串
writer.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+in.readLine());
//从Client读入一字符串,并打印到标准输出上
line=br.readLine();
//从系统标准输入读入一字符串
} //继续循环
//5、关闭资源
writer.close(); //关闭Socket输出流
in.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e) {//出错,打印出错信息
System.out.println("Error."+e);
}
}
}
客户端代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
public class SocketClient {
// 搭建客户端
public static void main(String[] args) throws IOException {
try {
// 1、创建客户端Socket,指定服务器地址和端口
Socket socket=new Socket("127.0.0.1",3900);
System.out.println("客户端启动成功");
// 2、获取输出流,向服务器端发送信息
// 向本机的3900端口发出客户请求
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 构造BufferedReader对象
PrintWriter write = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
//3、获取输入流,并读取服务器端的响应信息
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
String readline;
readline = br.readLine(); // 从系统标准输入读入一字符串
while (!readline.equals("end")) {
// 若从标准输入读入的字符串为 "end"则停止循环
write.println(readline);
// 将从系统标准输入读入的字符串输出到Server
write.flush();
// 刷新输出流,使Server马上收到该字符串
System.out.println("Client:" + readline);
// 在系统标准输出上打印读入的字符串
System.out.println("Server:" + in.readLine());
// 从Server读入一字符串,并打印到标准输出上
readline = br.readLine(); // 从系统标准输入读入一字符串
} // 继续循环
//4、关闭资源
write.close(); // 关闭Socket输出流
in.close(); // 关闭Socket输入流
socket.close(); // 关闭Socket
} catch (Exception e) {
System.out.println("can not listen to:" + e);// 出错,打印出错信息
}
}
}
服务器代码(多线程/多客户端)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketService {
// 搭建服务器端
public static void main(String[] args) throws IOException {
SocketService socketService = new SocketService();
// 1、a)创建一个服务器端Socket,即SocketService
socketService.oneServer();
}
public void oneServer() {
try {
ServerSocket server = null;
try {
server = new ServerSocket(3900);
// b)指定绑定的端口,并监听此端口。
System.out.println("服务器启动成功");
// 创建一个ServerSocket在端口3900监听客户请求
} catch (Exception e) {
System.out.println("没有启动监听:" + e);
// 出错,打印出错信息
}
Socket socket = null;
int i = 0;
int count = 100;// 限制最大连接为100
while (i++ < count) {
try {
socket = server.accept();
System.out.println("当前连接数量:" + i);
// 2、调用accept()方法开始监听,等待客户端的连接
// 使用accept()阻塞等待客户请求,有客户
// 请求到来则产生一个Socket对象,并继续执行
Handler handler = new Handler(socket, i);
new Thread(handler).start();
} catch (Exception e) {
System.out.println("Error." + e);
// 出错,打印出错信息
}
}
server.close(); // 关闭ServerSocket
} catch (Exception e) {// 出错,打印出错信息
System.out.println("Error." + e);
}
}
}
class Handler implements Runnable {
private Socket socket;
private int i;
public Handler(Socket socket, int i) {
this.socket = socket;
this.i = i;
}
public void run() {
BufferedReader in = null;
PrintWriter writer = null;
BufferedReader br = null;
try {
// 3、获取输入流,并读取客户端信息
String line;
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
// 由Socket对象得到输入流,并构造相应的BufferedReader对象
writer = new PrintWriter(socket.getOutputStream());
// 由Socket对象得到输出流,并构造PrintWriter对象
br = new BufferedReader(new InputStreamReader(System.in));
// 由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+ i + ":" + in.readLine());
// 在标准输出上打印从客户端读入的字符串
line = br.readLine();
// 从标准输入读入一字符串
// 4、获取输出流,响应客户端的请求
while (!line.equals("end")) {
// 如果该字符串为 "bye",则停止循环
writer.println(line);
// 向客户端输出该字符串
writer.flush();
// 刷新输出流,使Client马上收到该字符串
System.out.println("Server:" + line);
// 在系统标准输出上打印读入的字符串
System.out.println("Client" + i + ":" + in.readLine());
// 从Client读入一字符串,并打印到标准输出上
line = br.readLine();
// 从系统标准输入读入一字符串
} // 继续循环
} catch (Exception e) {
System.out.println("Error." + e);
// 出错,打印出错信息
} finally {
// 5、关闭资源
try {
writer.close(); // 关闭Socket输出流
in.close();
socket.close(); // 关闭Socket
} catch (IOException e) {
System.out.println("Error." + e);
// 出错,打印出错信息
} // 关闭Socket输入流
}
}
}
叁考资料:http://www.cnblogs.com/wisdo/p/5860001.html
http://blog.csdn.net/qq_23473123/article/details/51461894
相关文章推荐
- JAVA Socket编程学习9--Netty入门之Hello World!
- JAVA Socket编程学习8--为什么使用Netty
- Java学习(六):Socket编程实例
- java网络编程学习笔记(三):ServerSocket详解
- 【Java学习笔记】39:简易Socket编程(基于java.net下的Socket和ServerSocket)
- JAVA Socket编程学习7--NIO同时接收TCP和UDP数据
- 面向套接字(Socket)Java编程(单线程+多线程)
- java网络编程Socket学习(一)
- [零散篇]Java学习笔记---Java的Socket网络编程以及多线程
- JAVA Socket编程学习6--NIOTCP两个线程监听两个端口
- JAVA学习笔记- Socket编程
- java学习笔记——socket编程
- 【幻化万千戏红尘】qianfengDay23-java基础学习:网络编程、TCP IP协议、端口Socket、ServerSocket
- java网络编程Socket学习(一)
- java网络编程Socket学习(二)
- 【Java学习笔记】23.网络编程--Socket
- 某科学的超 Java网络编程:Socket通信原理及实例学习
- java网络编程Socket学习(二)
- Java网络编程学习笔记(六)服务器Socket
- JAVA Socket编程学习1--系统间通信概述