在前面的文章中讲了基于NIO实现的Server/Client。本文就讲讲基于同步堵塞式I/O实现的Server/Client好与前面的NIO中的Server/Client进行对照。

网络编程中须要解决的两个主要问题:

1、怎样准确的定位网络上的一台或多台主机。

2、找到主机后怎样可靠高效的进行传输数据。

而解决这两个问题的主要方式就是非常好的运用TCP/IP协议。所以我们所做的网络编程都是基于TCP/IP来实现的。

基于Socket的java网络编程的通信过程:

server:使用ServerSocket监听它指定的port,等待client连接请求。client连接后,产生会话,在会话结束之后。关闭连接。

client:使用Socket对网络的某一服务的某一port发出连接请求。一旦连接成功。打开会话,会话完毕之后,关闭连接。

对一个功能齐全的Socket,都要包括下面的基本结构,当中过程包括下面四步:

1、创建Socket

2、打开连接到Socket的输入输出流

3、依照一定的协议对Socket进行读/写操作

4、关闭Socket

详细代码示比例如以下:

实现单线程

server端程序:

package IOSocket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket; /**
* server的工作就是在指定的端口上监听
* 建立连接
* 打开输出流
* 封装输出流
* 向client发送数据
* 关闭打开的输出流
* 关闭打开的Socket对象
* server端的程序,在while循环中所运行的动作
* 听。说,听,说...
* @author Administrator
*
*/
public class Server2 {
private static final int port = 12345;
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(port);
//socket对象调用accept方法,等待请求的连接
System.out.println("server已启动,等待请求...");
Socket s = ss.accept();
//打开并封装输出流
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
//打开并封装输入流
DataInputStream dis = new DataInputStream(s.getInputStream());
//封装并读取键盘上的输入流
BufferedReader br = new BufferedReader
(new InputStreamReader(System.in));
String info;
while(true){
//接收client发过来的信息
info = dis.readUTF();
System.out.println("client说:"+info);
//假设发现对方说bye,则结束会话
if(info.equals("bye")){
break;
}
//读取键盘上的输入流,写入client
info = br.readLine();
dos.writeUTF(info);
//假设server自己说bye,也结束会话
if(info.equals("bye")){
break;
}
}
dis.close();
dos.close();
s.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("网络连接异常,退出程序...");
}
}
}

client程序:

package IOSocket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket; /**
* 创建socket对象,指定server的ip地址和server监听的端口号
* client在new的时候,就发出了连接请求,server端就会进行处理
* client在while循环中运行操作:
* 听,说,听,说...
*
*/
public class Client2 {
private final static String host = "localhost";
private final static int port = 12345;
public static void main(String[] args) {
try {
Socket s = new Socket(host,port);
System.out.println("client启动,发送请求...");
//打开并封装输出流
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
//打开并封装输入流
DataInputStream dis = new DataInputStream(s.getInputStream());
//读取并封装键盘输入流
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String info;
while(true){
//client先读取键盘输入信息
info = br.readLine();
//写入到server
dos.writeUTF(info);
//假设client自己说bye,即结束对话
if(info.equals("bye")){
break;
}
//接收server端信息
info = dis.readUTF();
System.out.println("server说: "+ info);
if(info.equals("bye")){
break;
}
}
dis.close();
dos.close();
s.close(); } catch (Exception e) {
e.printStackTrace();
}
}
}

实现多线程

服务端程序:

package IOSocket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket; public class Server3 {
private final static int port = 12345;
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
try {
System.out.println("server端启动,等待...");
ss = new ServerSocket(port);
s = ss.accept();
//打开并封装输出流
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
//打开并封装输入流
DataInputStream dis = new DataInputStream(s.getInputStream());
new Thread(new MyServerReader(dis)).start();
new Thread(new MyServerWriter(dos)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//接受并打印client传过来的信息
class MyServerReader implements Runnable{
private DataInputStream dis;
public MyServerReader(DataInputStream dis){
this.dis = dis;
}
@Override
public void run() {
String info;
while(true){
//假设对方,即client没有说话,那么就会堵塞在这里
//可是这里的堵塞并不会影响其他的线程
try {
info = dis.readUTF();
//假设状态由堵塞变为非堵塞,那么就答应接收到的信息
System.out.println("client说:"+info);
if("bye".equals(info)){
System.out.println("退出程序!");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//从键盘获取输入流并写入信息到client
class MyServerWriter implements Runnable{
private DataOutputStream dos;
public MyServerWriter(DataOutputStream dos){
this.dos = dos;
}
@Override
public void run() {
//读取键盘上的输入流
InputStreamReader isr = new InputStreamReader(System.in);
//封装键盘的输入流
BufferedReader br = new BufferedReader(isr);
String info;
while(true){
try {
info = br.readLine();
dos.writeUTF(info);
if("bye".equals(info)){
System.out.println("自己退出程序!");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

client程序:

package IOSocket;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket; public class Client3 {
private final static String host = "localhost";
private final static int port = 12345;
public static void main(String[] args) {
Socket s = null;
try {
s = new Socket(host,port);
System.out.println("client启动,发送消息...");
//打开并封装输入流
DataInputStream dis = new
DataInputStream(s.getInputStream());
//打开并封装输出流
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
new Thread(new MyClientReader(dis)).start();
new Thread(new MyClientWriter(dos)).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//接收server端传过来的信息
class MyClientReader implements Runnable{
private DataInputStream dis;
public MyClientReader(DataInputStream dis){
this.dis = dis;
}
@Override
public void run() {
String info;
while(true){
try {
info = dis.readUTF();
System.out.println("server说:"+info);
if("bye".equals(info)){
System.out.println("对方下线,退出程序!");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//从键盘获得输入流并写入信息到服务端
class MyClientWriter implements Runnable{
private DataOutputStream dos;
public MyClientWriter(DataOutputStream dos){
this.dos = dos;
}
@Override
public void run() {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String info;
while(true){
try {
info = br.readLine();
dos.writeUTF(info);
if("bye".equals(info)){
System.out.println("自己下线,退出程序!");
System.exit(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

參考资料:http://www.cnblogs.com/hongten/archive/2012/04/29/java_socket.html

基于I/O的Server/Client实现的更多相关文章

  1. 怎样基于谷歌地图的Server缓存公布Image Service服务

    怎样基于谷歌地图的Server缓存公布Image Service服务 第一步:下载地图数据 下载安装水经注万能地图下载器,启动时仅仅选择电子.谷歌(这里能够依据自己的须要选择).例如以下图所看到的. ...

  2. Consul集群Server+Client模式

    Consul集群Server+Client模式 架构示意图 只使用Consul的Server模式有以下2个问题: 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题. Serve ...

  3. 基于iSCSI的SQL Server 2012群集测试(四)--模拟群集故障转移

    6.模拟群集故障转移 6.1 模拟手动故障转移(1+1) 模拟手动故障转移的目的有以下几点: 测试群集是否能正常故障转移 测试修改端口是否能同步到备节点 测试禁用full-text和Browser服务 ...

  4. NetMQ(ZeroMQ)Client => Server => Client 模式的实现

    ØMQ (也拼写作ZeroMQ,0MQ或ZMQ)是一个为可伸缩的分布式或并发应用程序设计的高性能异步消息库.它提供一个消息队列, 但是与面向消息的中间件不同,ZeroMQ的运行不需要专门的消息代理(m ...

  5. C# .net基于Http实现web server(web服务)

    原文:C# .net基于Http实现web server(web服务) 什么是 web server?  百度百科是这么解释的: Web Server中文名称叫网页服务器或web服务器.WEB服务器也 ...

  6. 基于moco的mock server 简单应用 来玩玩吧

    提起mock大家应该就知道是干嘛用的了,再次再介绍一种简单的方式,基于moco的mock server.步骤很简单: 1. 首先,要下载个moco的jar0_1482402640757_moco-ru ...

  7. docker报Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.19)

    docker version Client: Version: 17.05.0-ce API version: 1.24 (downgraded from 1.29) Go version: go1. ...

  8. Redis2.2.2源码学习——Server&Client链接的建立以及相关Event

    Redis中Server和User建立链接(图中的client是服务器端用于描述与客户端的链接相关的信息) Redis Server&Client链接的建立时相关Event的建立(图中的cli ...

  9. Socket编程--基础(基本server/client实现)

    IPv4套接口地址结构 IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中 LINUX结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...

随机推荐

  1. LocalDateTime查找最近的五分钟点

    /** * 最近的五分钟 * @param dateTime * @return */ public static LocalDateTime getNear5(LocalDateTime dateT ...

  2. POJ 1111(数字很吉利嘛) 简单BFS

    Image Perimeters Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8594 Accepted: 5145 Desc ...

  3. B - Substrings Sort

    Problem description You are given nn strings. Each string consists of lowercase English letters. Rea ...

  4. Spring Cloud (3) 服务消费者-Ribbon

    在上一篇中使用LoadBalancerClient接口实现了获取某个服务的具体实例,并根据实例信息发起服务接口消费请求.但是这样的做法需要我们手工的区编写服务选取.连接拼接等繁琐的工作,对于开发人员来 ...

  5. SQLServer2008 去除换行符

    declare @str varchar(8000)set @str='SQL语句' select replace(@str,char(10),'')

  6. SQLServer2008 有用的判断函数

    ISNULL(参数1,参数2) 若参数1为空,则返回参数2 NULLIF(参数1,参数2) 若参数1和参数2不等,则返回参数1 若参数1和参数2相等,则返回NULL 例子:ISNULL(NULLIF( ...

  7. nodejs 中使用 mysql 实现 crud

    首先要使用 mysql 就必须要安装 npm install mysql 然后封装 sql 函数 const mySql = require('mysql'); let connection ; le ...

  8. CSS清除浮动_清除float浮——详解overflow:hidden 与clear:both属性

    最近刚好碰到这个问题,看完这个就明白了.写的很好,所以转载了! CSS清除浮动_清除float浮动 CSS清除浮动方法集合 一.浮动产生原因   -   TOP 一般浮动是什么情况呢?一般是一个盒子里 ...

  9. Redis配置文件各项参数说明及性能调优

    Redis配置文件参数说明: 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 daemonize no 2. 当Redis以守护进程方式运行时,Redis默 ...

  10. Android 概览屏幕

    文章照搬过来的:原文地址https://developer.android.google.cn/guide/components/recents.html 概览屏幕(也称为最新动态屏幕.最近任务列表或 ...