基于I/O的Server/Client实现
在前面的文章中讲了基于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实现的更多相关文章
- 怎样基于谷歌地图的Server缓存公布Image Service服务
怎样基于谷歌地图的Server缓存公布Image Service服务 第一步:下载地图数据 下载安装水经注万能地图下载器,启动时仅仅选择电子.谷歌(这里能够依据自己的须要选择).例如以下图所看到的. ...
- Consul集群Server+Client模式
Consul集群Server+Client模式 架构示意图 只使用Consul的Server模式有以下2个问题: 因为Consul Server数量受到控制所以压力承载(扩展性)是个问题. Serve ...
- 基于iSCSI的SQL Server 2012群集测试(四)--模拟群集故障转移
6.模拟群集故障转移 6.1 模拟手动故障转移(1+1) 模拟手动故障转移的目的有以下几点: 测试群集是否能正常故障转移 测试修改端口是否能同步到备节点 测试禁用full-text和Browser服务 ...
- NetMQ(ZeroMQ)Client => Server => Client 模式的实现
ØMQ (也拼写作ZeroMQ,0MQ或ZMQ)是一个为可伸缩的分布式或并发应用程序设计的高性能异步消息库.它提供一个消息队列, 但是与面向消息的中间件不同,ZeroMQ的运行不需要专门的消息代理(m ...
- C# .net基于Http实现web server(web服务)
原文:C# .net基于Http实现web server(web服务) 什么是 web server? 百度百科是这么解释的: Web Server中文名称叫网页服务器或web服务器.WEB服务器也 ...
- 基于moco的mock server 简单应用 来玩玩吧
提起mock大家应该就知道是干嘛用的了,再次再介绍一种简单的方式,基于moco的mock server.步骤很简单: 1. 首先,要下载个moco的jar0_1482402640757_moco-ru ...
- 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. ...
- Redis2.2.2源码学习——Server&Client链接的建立以及相关Event
Redis中Server和User建立链接(图中的client是服务器端用于描述与客户端的链接相关的信息) Redis Server&Client链接的建立时相关Event的建立(图中的cli ...
- Socket编程--基础(基本server/client实现)
IPv4套接口地址结构 IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中 LINUX结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...
随机推荐
- 洛谷P2593 [ ZJOI 2006 ] 超级麻将 —— DP
题目:https://www.luogu.org/problemnew/show/P2593 DP的话,考虑到当前这一位只跟前两位有关,所以记录一下这3位的状态就行: 于是一开始记录的第 i 位,i- ...
- 3-4 第三天 Generator生成器
Generator是ES6里面的新增规范,ES6其实就是ES2015.ES5.ES6.ES7这些术语大家上网一查就都明白了.JavaScript是一个范程,就是我们说的JS.ES就是ECMA Scri ...
- PCB MS SQL 行转列
一.原数据: SELECT inman,indate FROM [fp_db].[dbo].[ppezhpbb] WHERE indate > '2016-5-1' AND indate < ...
- Python可迭代序列排序总结
列表排序 示例:lst = [12, 6, 1, 3, 10] 方法一:使用sort def list_sort(lst): lst.sort() # 就地排序,没有返回值 return lst 补充 ...
- iOS开发之判断手机号和邮箱 正则表达式
#pragma mark --判断手机号合法性 + (BOOL)checkPhone:(NSString *)phoneNumber { NSString *regex = @"^((13[ ...
- CSS的常用属性(二)
盒子模型之边框 border-(top/bottom/left/right)-style: solid 边框的风格 如(solid 实线,dotted 点线,dashed 虚线) border-top ...
- 常用SQL函数
—————常用SQL函数(实例简述)————— 数据库环境:DB2数据库: 执行工具:Toad for DB2 1.转字符串:to_char() 日期类型:to_char(birthday,'yyy ...
- JavaScript自动计算价格和全选
JavaScript自动计算价格和全选,价格自增加减,复选框,反选,全选. 如图: 如图: CSS代码 @charset "gb2312"; /* CSS Document */ ...
- 安装rails卡住很慢 出现302 Moved Temporarily
在MAC上安装rails的时候,使用命令$ gem install rails 发现一直没响应,使用$ gem install rails-V命令发现,安装会在中间卡住,出现302 Moved Tem ...
- sql server数据库可疑状态解决方法
前段时间客户数据服务器断电,开机后发现数据库状态标记为可疑,可能是断电引起的数据库日志文件损坏,修复方法如下: 只有mdf文件,重建日志: --注:example为测试用数据库,相应的Example_ ...