在前面的文章中讲了基于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. JS文件中的中文在网页上显示为乱码解决方法

    转自:http://www.pc6.com/infoview/Article_63835.html 如果JS文件中的中文在网页上显示为乱码,不妨采用本文章中的方法来试一试,或许能解决使你很头疼的问题. ...

  2. 《疯狂Python讲义》重要笔记--变量

    一个Python解释器 接下来的旅程——你需要下载好Python,Python解释器通常放在 /usr/local/bin/python3.7 ; 在Unix系统的bash中输入 where pyth ...

  3. C# 设置百分比保留2位数

    double a=50; double b=100; 没有小数部分Label1.Text = (a   /   (a+b)).ToString("0%")   两位小数Label2 ...

  4. 1.ArcGis几何图形之几何计算

    /// <summary> /// 检测几何图形A是否包含几何图形B /// </summary> /// <param name="pGeometryA&qu ...

  5. C#三种创建对象方法所需时间比较。。。。。

    C#创建对象的三种方法  new().Activator.Assembly,接下来通过代码直接来看看运行的速度.... 首先,先看看三种创建对象实例的方法: //new(); public stati ...

  6. 1.java安全框架SHIRO

    1. shiro介绍 Apache Shiro是一个强大且易用的java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移 ...

  7. SQLCE本地数据库

    SQLCE是一个标准得关系数据库,可以使用 LINQ 和DateContext来处理本地数据库数据库. 使用SQLCE 要在代码中使用本地数据库功能,需要添加以下命名空间 : using System ...

  8. css的选择器效率分析

    我们都知道,CSS具有叠加性(同一个元素被多条样式规则指定),继承性(后代元素会继承前辈元素的一些样式和属性)和优先级 (由于CSS的叠加性和继承性,将产生优先级,这指的是哪条样式规则会最终作用于指定 ...

  9. js截取字符串测试

    function gget() { $.ajax({ type: "GET", url: "index", data: { U: '1234', P: '000 ...

  10. [转]使用Fiddler进行iOS APP的HTTP/HTTPS抓包

    Fiddler不但能截获各种浏览器发出的HTTP请求, 也可以截获各种智能手机发出的HTTP/HTTPS请求.Fiddler能捕获iOS设备发出的请求,比如IPhone, IPad, MacBook. ...