基于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结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...
随机推荐
- Spring Data 自动生成
之前一直用的mybatis逆向自动生成,由于最近学习springdata,所以看了一下springdata的自动生成,基本与mybatis一致,不同的也许就是逆向生成代码(实体类,mapper等)和正 ...
- Python简介和基础入门
1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是一种开发语言,而且已经 ...
- cocos2d-x https
cocos2d-x :2.1.3HttpClient.cpp文件中 bool configureCURL(CURL *handle)后边添加如下两句: curl_easy_setopt(handle ...
- C#Cookie操作类,删除Cookie,给Cookie赋值
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...
- 【转】SQL SERVER 主体,已同步
转自郭大侠博客: https://www.cnblogs.com/gered/p/10601202.html 目录 SQL SERVER 基于数据库镜像的主从同步... 1 1.概念... 2 1. ...
- java的封箱和拆箱
1.基本概念 字节的单位:byte.位的单位:bit,1byte=8bit 2.8种基本数据类型 4种整型,2种浮点类型,1种用于表示Unicode编码的字符单元的字符类型和1种用于表示真值的bool ...
- SecureCRT连接Ubuntu报The remote system refused the connection.解决方案
使用SecureCRT连接到远程Ubuntu,连接失败报The remote system refused the connection. 进入Ubuntu系统,终端中敲入以下命令: ps -ef|g ...
- 总结:Ruby里是值传递还是引用传递
在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference).ruby中变量都是对象的引用. 先来看 def pref2(agr) agr.downcase e ...
- 省市区县的sql语句——城市
/*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...
- 阶乘问题-----sum随变量改变而改变