Socket


java Socket 编程
                     Socket用于网络连接,其中封装了主机的名称,IP地址,端口号等相关信息。使用IO进行读写数据。

网络连接常用的模型
C/S模型
Client/Server  客户端对服务端

B/S模式
浏览器/服务器  一种特殊的C/S
统一了客户端:浏览器
统一了通信协议:http协议

java实现网路通信
两个重要的类
ServerSocket 服务端Socket
 
Socket         客户端Socket

ServerSocket运行在服务端,Socket运行在客户端。
连接步骤:
1:创建ServerSocket
2:创建客户端Socket
3:打开输入输出流
4:进行读写操作达到通信的目的
5:关闭连接

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 * @author Administrator
 *
 */
public class Server {
	//服务端Socket
	private ServerSocket server;
	
	public Server(){
		//网络连接一定要捕获异常
		try {
			/**
			 * 创建服务端的时候要指定服务端口号
			 */
			server = new ServerSocket(8088);	
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 用于接收客户端的连接
	 */
	public void start(){
		try {
			/**
			 * 在8088端口上监听客户端的连接
			 * accept方法为阻塞方法,直到客户端连接才会返回
			 * 返回的就是封装了客户端信息的Socket
			 */
			while(true){
				System.out.println("等待客户端连接。。。");
			  Socket socket = server.accept();	
				System.out.println("一个客户端连接了!");
				/**
				 * 当一个客户端连接上后,启动一个线程
				 * 并将这个Socket交给这个线程,让线程
				 * 循环读取这个客户端发送过来的信息并
				 * 输出到控制台
				 */
				ClientHandler handler = 
					new ClientHandler(socket);
				Thread t = new Thread(handler);
				t.start();
			}
		} catch (Exception e) {
			
		}
	}
	
	public static void main(String[] args) {
		//创建服务端实例
		Server server = new Server();
		server.start();
	}
	
	/**
	 * 创建一个线程类,用于接收客户端发送过来的信息
	 */
	public class ClientHandler implements Runnable{
		/**
		 * 当前线程处理的客户端的Socket
		 */
		private Socket client;
		public ClientHandler(Socket client){
			this.client = client;
		}
		public void run(){
			try{
				//获取客户端的输入流,用于读取客户端发送过来的信息
				InputStream in = client.getInputStream();
				//包装为用于读取字符串的缓冲字符输入流
				BufferedReader reader = 
					new BufferedReader(
							new InputStreamReader(
									in
							)
					);
				String str = null;
				while(true){
					str = reader.readLine();
					System.out.println("客户端说:"+str);
				}
				
			}catch(Exception e){
				
			}
		}
	}
	
}








MINA框架
Socket的开源框架
中国很多流行的游戏后台服务器都使用它

当用户频繁的登录和登出,我们的服务端就会频繁的创建线程和销毁线程。这样做会给服务器带来不少不必要的开销。为了解决频繁创建和销毁线程,让线程能够得到最大程度的重用,java提供了一个技术,线程池。

线程池的实现原理:
首先创建一些空的线程(不执行任何任务),当有一个任务时(Runnable),则取出一个线程来运行这个任务,当任务运行完毕后,不销毁线程,而是回收线程等待下次使用。

java中线程池类
ExecutorService
用于管理线程池的启动,终止等操作。

创建线程池
Executors用来创建不同类型的线程池
1:
Executors.newCachedThreadPool()
创建一个根据需要创建新线程的线程池,在这些线程空闲时可以重用他们。

2:
Executors.newFixedThreadPool(int size)
创建一个指定大小的线程池,当线程空闲时可以重用。

3:
Executors.new ScheduledThreadPool(int)
可以将任务指定一个延迟时间,在延迟时间过后再执行任务的固定大小的线程池

4:
Executors.newSingleThreadExecutor()
只有一个线程,当线程处于运行状态时,其他任务都需要等待。

多线程使用队列时,因为要考虑线程安全问题,所以我们必须要做的事情是将添加元素和获取元素的操作同步,就是多线程不能同时存取元素。在高并发情况下,这样的效率比较低。

双缓冲队列
内部维护两个队列,这样做可以实现同一时刻一个线程存(offer),另一个线程取(poll)。
原理是
A线程存元素时,向A队列添加,B线程取元素时从B队列取,当两个操作完成后,交换。
使用双缓冲队列,起码可以实现同时进行存取工作,但是,还是不能同时存或同时取。

BlockingDeque双缓冲队列

1:ArrayBlockingDeque:规定大小的    BlockingDeque,构造方法含有一个int型参数
  用于指定队列大小。队列存取本着FIFO(    先进先出 First Input First Output)
  当队列元素满了时,新添加元素则进行排队   等待,offer有个重载方法,  允许设置超时    时间,超时时间过后还没能添加则放弃,打    断等待会抛出异常。

2:LinkedBlockingDeque:不定长队列,可根据   需要添加元素。该队列允许的最大值为    Integer.MAX_VALUE。
  LinkedBlockingDeque也支持有int参数的构    造方法,可以指定队列大小。
  存取数据本着先入先出原则(FIFO)

3:PriorityBlockDeque:和     LinkedBlockingDeque一样,但是存去元素   本着自然排序原则。同样的,该队列有一个   重载的构造方法,允许我们传入一     Comparator,按照我们指定的比较规则进  行排序
 
4: SynchronousQueue:一个比较特殊的    BlockingDeque,存取元素必须同步,存一        次取一次。交替进行。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值