在前面的文章中讲了基于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. bzoj 3598 [ Scoi 2014 ] 方伯伯的商场之旅 ——数位DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3598 数位DP...东看西看:http://www.cnblogs.com/Artanis/ ...

  2. 3个不常用的HTML标签

    html标签众多,在HTML手册里你可以都查到.但有的HTML标签你可能从未使用过.不是因为你欠缺学习精神,而是它们确实用处不大.如果你有探索精神,那就接着往下看吧. 第一个:<abbr> ...

  3. 正确的缩写document。querySelector

    北京的夕阳,伴随淡淡的霾殇.从写字楼望去,光线是那么昏黄.没有孤雁,也没有霞光,遥想当年,还是 jQuery 独霸一方.那时的我们,写程序都习惯了使用 $,至少在对美元符号的喜爱上,与 PHP 达成了 ...

  4. JavaScript中变速运动的数学模型构建

    AB两地直线距离相距为S,机器人β从A点向B点行进.已知机器人β的每间隔固定时间行进一段路程,其下次行进的距离为当前距离B点路程的1/q(q为正整数),求机器人第n次行进距离的表达式an以及前n项和公 ...

  5. cocos2d-x https

    cocos2d-x :2.1.3HttpClient.cpp文件中  bool configureCURL(CURL *handle)后边添加如下两句: curl_easy_setopt(handle ...

  6. SQLServer2008 关于Group by

    如果我们想知道每个国家有多少种水果,那么我们可以通过如下SQL语句来完成: SELECT COUNT(*) FruitName AS 水果种类, ProductPlace AS 出产国 FROM T_ ...

  7. ES6 Template String 模板字符串

    模板字符串(Template String)是增强版的字符串,用反引号(`)标识,它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量. 大家可以先看下面一段代码: $(&quo ...

  8. mySQL用代码添加表格内容 删除数据方法

    通过代码对表格内容操作: 1.添加数据insert into Info values('p009','张三',1,'n001','2016-8-30 12:9:8') ; 给特定的列添加数据inser ...

  9. XML、集合、JSP综合练习

    一.利用DOM解析XML文件得到信息:存入泛型集合中在JSP页面循环打印读取的信息 a)         编写XML文件:添加测试节点数据 b)         建立web项目:在JSP页面中使用DO ...

  10. 对学Oracle数据库初学者的开场篇

    前言:因为项目原因,近期开始学习Oracle数据库.Oracle是目前最流行的数据库之一,功能强大,性能卓越,相对的学习的难度还是不小.我打算将自己的学习过程记录下来,做个积累,方便自己和其他的学习者 ...