在前面的文章中讲了基于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端程序:

  1. package IOSocket;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10.  
  11. /**
  12. * server的工作就是在指定的端口上监听
  13. * 建立连接
  14. * 打开输出流
  15. * 封装输出流
  16. * 向client发送数据
  17. * 关闭打开的输出流
  18. * 关闭打开的Socket对象
  19. * server端的程序,在while循环中所运行的动作
  20. * 听。说,听,说...
  21. * @author Administrator
  22. *
  23. */
  24. public class Server2 {
  25. private static final int port = 12345;
  26. public static void main(String[] args) {
  27. try {
  28. ServerSocket ss = new ServerSocket(port);
  29. //socket对象调用accept方法,等待请求的连接
  30. System.out.println("server已启动,等待请求...");
  31. Socket s = ss.accept();
  32. //打开并封装输出流
  33. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  34. //打开并封装输入流
  35. DataInputStream dis = new DataInputStream(s.getInputStream());
  36. //封装并读取键盘上的输入流
  37. BufferedReader br = new BufferedReader
  38. (new InputStreamReader(System.in));
  39. String info;
  40. while(true){
  41. //接收client发过来的信息
  42. info = dis.readUTF();
  43. System.out.println("client说:"+info);
  44. //假设发现对方说bye,则结束会话
  45. if(info.equals("bye")){
  46. break;
  47. }
  48. //读取键盘上的输入流,写入client
  49. info = br.readLine();
  50. dos.writeUTF(info);
  51. //假设server自己说bye,也结束会话
  52. if(info.equals("bye")){
  53. break;
  54. }
  55. }
  56. dis.close();
  57. dos.close();
  58. s.close();
  59. ss.close();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. System.out.println("网络连接异常,退出程序...");
  63. }
  64. }
  65. }

client程序:

  1. package IOSocket;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.InputStreamReader;
  7. import java.net.Socket;
  8.  
  9. /**
  10. * 创建socket对象,指定server的ip地址和server监听的端口号
  11. * client在new的时候,就发出了连接请求,server端就会进行处理
  12. * client在while循环中运行操作:
  13. * 听,说,听,说...
  14. *
  15. */
  16. public class Client2 {
  17. private final static String host = "localhost";
  18. private final static int port = 12345;
  19. public static void main(String[] args) {
  20. try {
  21. Socket s = new Socket(host,port);
  22. System.out.println("client启动,发送请求...");
  23. //打开并封装输出流
  24. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  25. //打开并封装输入流
  26. DataInputStream dis = new DataInputStream(s.getInputStream());
  27. //读取并封装键盘输入流
  28. BufferedReader br = new BufferedReader(
  29. new InputStreamReader(System.in));
  30. String info;
  31. while(true){
  32. //client先读取键盘输入信息
  33. info = br.readLine();
  34. //写入到server
  35. dos.writeUTF(info);
  36. //假设client自己说bye,即结束对话
  37. if(info.equals("bye")){
  38. break;
  39. }
  40. //接收server端信息
  41. info = dis.readUTF();
  42. System.out.println("server说: "+ info);
  43. if(info.equals("bye")){
  44. break;
  45. }
  46. }
  47. dis.close();
  48. dos.close();
  49. s.close();
  50.  
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }

实现多线程

服务端程序:

  1. package IOSocket;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.ServerSocket;
  9. import java.net.Socket;
  10.  
  11. public class Server3 {
  12. private final static int port = 12345;
  13. public static void main(String[] args) {
  14. ServerSocket ss = null;
  15. Socket s = null;
  16. try {
  17. System.out.println("server端启动,等待...");
  18. ss = new ServerSocket(port);
  19. s = ss.accept();
  20. //打开并封装输出流
  21. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  22. //打开并封装输入流
  23. DataInputStream dis = new DataInputStream(s.getInputStream());
  24. new Thread(new MyServerReader(dis)).start();
  25. new Thread(new MyServerWriter(dos)).start();
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. //接受并打印client传过来的信息
  32. class MyServerReader implements Runnable{
  33. private DataInputStream dis;
  34. public MyServerReader(DataInputStream dis){
  35. this.dis = dis;
  36. }
  37. @Override
  38. public void run() {
  39. String info;
  40. while(true){
  41. //假设对方,即client没有说话,那么就会堵塞在这里
  42. //可是这里的堵塞并不会影响其他的线程
  43. try {
  44. info = dis.readUTF();
  45. //假设状态由堵塞变为非堵塞,那么就答应接收到的信息
  46. System.out.println("client说:"+info);
  47. if("bye".equals(info)){
  48. System.out.println("退出程序!");
  49. System.exit(0);
  50. }
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }
  56. }
  57. //从键盘获取输入流并写入信息到client
  58. class MyServerWriter implements Runnable{
  59. private DataOutputStream dos;
  60. public MyServerWriter(DataOutputStream dos){
  61. this.dos = dos;
  62. }
  63. @Override
  64. public void run() {
  65. //读取键盘上的输入流
  66. InputStreamReader isr = new InputStreamReader(System.in);
  67. //封装键盘的输入流
  68. BufferedReader br = new BufferedReader(isr);
  69. String info;
  70. while(true){
  71. try {
  72. info = br.readLine();
  73. dos.writeUTF(info);
  74. if("bye".equals(info)){
  75. System.out.println("自己退出程序!");
  76. System.exit(0);
  77. }
  78. } catch (IOException e) {
  79. e.printStackTrace();
  80. }
  81. }
  82. }
  83. }

client程序:

  1. package IOSocket;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataInputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.IOException;
  7. import java.io.InputStreamReader;
  8. import java.net.Socket;
  9.  
  10. public class Client3 {
  11. private final static String host = "localhost";
  12. private final static int port = 12345;
  13. public static void main(String[] args) {
  14. Socket s = null;
  15. try {
  16. s = new Socket(host,port);
  17. System.out.println("client启动,发送消息...");
  18. //打开并封装输入流
  19. DataInputStream dis = new
  20. DataInputStream(s.getInputStream());
  21. //打开并封装输出流
  22. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  23. new Thread(new MyClientReader(dis)).start();
  24. new Thread(new MyClientWriter(dos)).start();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. //接收server端传过来的信息
  31. class MyClientReader implements Runnable{
  32. private DataInputStream dis;
  33. public MyClientReader(DataInputStream dis){
  34. this.dis = dis;
  35. }
  36. @Override
  37. public void run() {
  38. String info;
  39. while(true){
  40. try {
  41. info = dis.readUTF();
  42. System.out.println("server说:"+info);
  43. if("bye".equals(info)){
  44. System.out.println("对方下线,退出程序!");
  45. System.exit(0);
  46. }
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. }
  52. }
  53. //从键盘获得输入流并写入信息到服务端
  54. class MyClientWriter implements Runnable{
  55. private DataOutputStream dos;
  56. public MyClientWriter(DataOutputStream dos){
  57. this.dos = dos;
  58. }
  59. @Override
  60. public void run() {
  61. InputStreamReader isr = new InputStreamReader(System.in);
  62. BufferedReader br = new BufferedReader(isr);
  63. String info;
  64. while(true){
  65. try {
  66. info = br.readLine();
  67. dos.writeUTF(info);
  68. if("bye".equals(info)){
  69. System.out.println("自己下线,退出程序!");
  70. System.exit(0);
  71. }
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. }
  75. }
  76. }
  77. }

參考资料: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. Spring Data 自动生成

    之前一直用的mybatis逆向自动生成,由于最近学习springdata,所以看了一下springdata的自动生成,基本与mybatis一致,不同的也许就是逆向生成代码(实体类,mapper等)和正 ...

  2. Python简介和基础入门

    1.1 Python是什么 相信混迹IT界的很多朋友都知道,Python是近年来最火的一个热点,没有之一.从性质上来讲它和我们熟知的C.java.php等没有什么本质的区别,也是一种开发语言,而且已经 ...

  3. cocos2d-x https

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

  4. C#Cookie操作类,删除Cookie,给Cookie赋值

    using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...

  5. 【转】SQL SERVER 主体,已同步

    转自郭大侠博客:  https://www.cnblogs.com/gered/p/10601202.html 目录 SQL SERVER 基于数据库镜像的主从同步... 1 1.概念... 2 1. ...

  6. java的封箱和拆箱

    1.基本概念 字节的单位:byte.位的单位:bit,1byte=8bit 2.8种基本数据类型 4种整型,2种浮点类型,1种用于表示Unicode编码的字符单元的字符类型和1种用于表示真值的bool ...

  7. SecureCRT连接Ubuntu报The remote system refused the connection.解决方案

    使用SecureCRT连接到远程Ubuntu,连接失败报The remote system refused the connection. 进入Ubuntu系统,终端中敲入以下命令: ps -ef|g ...

  8. 总结:Ruby里是值传递还是引用传递

    在ruby中一切都是对象,而你向方法中传递的实质上是对象的引用( object-reference).ruby中变量都是对象的引用. 先来看 def pref2(agr) agr.downcase e ...

  9. 省市区县的sql语句——城市

    /*SQLyog v10.2 MySQL - 5.5.48 : Database - 省市县****************************************************** ...

  10. 阶乘问题-----sum随变量改变而改变