`

Java Socket学习---单线程阻塞

阅读更多

这里首先介绍几个概念:BIO——同步阻塞IO、NIO——同步非阻塞IO、AIO——异步非阻塞IO

今天的例子是最简单的一个例子,没有引入多线程,仅仅是一个单线程阻塞的Socket例子,多线程的下次再继续。

 

这样子的例子仅仅供学习使用,基本上是没有实用意义的,因为在实际的应用中基本上是不止于一个Client的。

 

Server端得代码如下:

package com.henushang.socket;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

import com.henushang.socket.util.SocketUtils;

public class EchoServer {
	private int port = 8000;
	private ServerSocket serverSocket;
	
	public EchoServer() throws Exception {
		serverSocket = new ServerSocket(port);
		System.out.println("waitting connet...");
	}
	
	public String echo(String msg) {
		return "echo:" + msg;
	}
	
	public void service() {
		Socket socket = null;
		String msg = null;
 		while (true) {
			try {
				socket = serverSocket.accept();// 准备接受连接
				System.out.println("new connection: " + socket.getInetAddress() + ":" + socket.getPort());
				BufferedReader reader = SocketUtils.getReader(socket);// 输入流
				PrintWriter writer = SocketUtils.getWriter(socket);// 输出流
				while ((msg = reader.readLine()) != null) {// 接收消息
					System.out.println(msg);
					writer.println(echo(msg));// 发送消息
					writer.flush();// 注意,在使用缓冲流在发送消息的时候最好进行强制刷新,否则,可能会由于缓冲区不满而暂时不发送消息
					if ("bye".equals(msg)) {
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				SocketUtils.close(socket);
			}
		}
	}
	
	public static void main(String[] args) {
		try {
			new EchoServer().service();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}

 

客户端代码:

package com.henushang.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import com.henushang.socket.util.SocketUtils;

public class EchoClient {
	private String host = "127.0.0.1";
	private int port = 8000;
	private Socket socket ;
	
	public EchoClient() throws Exception {
		socket = new Socket(host, port);
	}
	
	public void talk() throws IOException {
		try {
			BufferedReader reader = SocketUtils.getReader(socket);
			PrintWriter writer = SocketUtils.getWriter(socket);
			// 读取本地控制台的消息
			BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
			String msg = null;
			while ((msg = localReader.readLine()) != null) {
				writer.println(msg);
				writer.flush();
				System.out.println(reader.readLine());
				if ("bye".equals(msg)) {
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			SocketUtils.close(socket);
		}
	}
	
	public static void main(String[] args) throws Exception{
		new EchoClient().talk();
	}
}

 

下面是我写的一个工具类,做了一些重复的操作的汇集,如下:

package com.henushang.socket.util;

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.nio.channels.SocketChannel;

public class SocketUtils {
	
	public static PrintWriter getWriter(Socket socket) throws IOException {
		OutputStream os = socket.getOutputStream();
		return new PrintWriter(os);
	}
	
	public static PrintWriter getWriter(SocketChannel socketChannel) throws IOException {
		return getWriter(socketChannel.socket());
	}
	
	public static BufferedReader getReader(Socket socket) throws IOException{
		InputStream is = socket.getInputStream();
		return new BufferedReader(new InputStreamReader(is, "UTF-8"));
	}
	
	public static BufferedReader getReader(SocketChannel socketChannel) throws IOException{
		return getReader(socketChannel.socket());
	}
	
	public static void close(Socket socket) {
		try {
			if (socket != null) {
				socket.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void close(SocketChannel socketChannel) {
		try {
			if (socketChannel != null) {
				socketChannel.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

参考:《java网络编程精解》

 

 

 

0
0
分享到:
评论

相关推荐

    基于javatcpsocket通信的拆包和装包源码-NettyTree:网状树

     1)单线程模型,所有的IO操作都在一个NIO线程上完成   存在性能和可靠性上的问题  2)多线程模型,有一组NIO线程处理IO操作   有一个专门的NIO线程-Acceptor线程用于监听服务端,接收客户端的TCP连接请求;   ...

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    新版Android开发教程.rar

    � Google 提供了一套 Java 核心包 (J2SE 5,J2SE 6) 的有限子集,尚不承诺遵守 Java 任何 Java 规范 , 可能会造 成J ava 阵营的进一步分裂。 � 现有应用完善度不太够,需要的开发工作量较大。--------------------...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    基于javatcpsocket通信的拆包和装包源码-Netty-practice:Netty学习实践

    NIO+单线程Reactor模型 NIO+多线程Reactor模型 NIO+主从多线程Reactor模型 总结 阻塞IO和非阻塞IO的区别就在于:应用程序的调用(等待数据准备阶段)是否立即返回! 同步IO和异步IO的区别就在于:数据访问(等待数据...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    7.1.5 Swing的单线程模型 145 7.2 练习 148 7.2.1 第1个Swing程序 148 7.2.2 外观感觉 150 7.2.3 事件侦听器 151 7.2.4 Swing基本控件和窗口 155 7.2.5 Swing容器 176 7.2.6 Swing高级控件 181 7.3 小结 187...

    JAVA基础课程讲义

    JAVA中如何实现多线程(重点!!) 168 通过继承Thread类实现多线程 168 通过Runnable接口实现多线程 169 线程状态和sleep/yield/join/stop/destroy方法 170 新生状态 170 就绪状态 170 运行状态 170 死亡状态 170 ...

    Java SE实践教程 源代码 下载

    7.1.5 Swing的单线程模型 145 7.2 练习 148 7.2.1 第1个Swing程序 148 7.2.2 外观感觉 150 7.2.3 事件侦听器 151 7.2.4 Swing基本控件和窗口 155 7.2.5 Swing容器 176 7.2.6 Swing高级控件 181 7.3 小结 187...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    7.1.5 Swing的单线程模型 145 7.2 练习 148 7.2.1 第1个Swing程序 148 7.2.2 外观感觉 150 7.2.3 事件侦听器 151 7.2.4 Swing基本控件和窗口 155 7.2.5 Swing容器 176 7.2.6 Swing高级控件 181 7.3 小结 187...

    java经典面试2010集锦100题(不看你后悔)

    JAVA试题(100道) —————————————————————————————————————— 题目1: 下面不属于基本类型的是:c (选择1项) A) boolean B) long C) String D) byte 题目2:d 如下程序中:...

    基于javatcpsocket通信的拆包和装包源码-DistributedSystemUsingJavaNIO:手把手教你使用JavaNIO构

    要写好一个分布式系统往往是一件比较复杂的事情,特别是使用Java、C++这类不具有并发原语的非函数式编程语言,不仅需要考虑各个线程之间的同步和并发,还要考虑进程以及节点之间的通信和协作。单就通信框架这一层...

    javaSE代码实例

    第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...

    详解node child_process模块学习笔记

    NodeJs是一个单进程的语言,不能像Java那样可以创建多线程来并发执行。当然在大部分情况下,NodeJs是不需要并发执行的,因为它是事件驱动性永不阻塞。但单进程也有个问题就是不能充分利用CPU的多核机制,根据前人的...

Global site tag (gtag.js) - Google Analytics