Java实现TCP之Echo客户端和服务端

代码内容

  • 采用TCP协议编写服务器端代码(端口任意)
  • 编写客户机的代码访问该端口
  • 客户机按行输入
  • 服务器将收到的字符流和接收到的时间输出在服务器console
  • 原样返回给客户机在客户机console显示出来

代码实现

  1. /* TCPEchoClient.java */
  2. import java.io.*;
  3. import java.net.*;
  4. public class TCPEchoClient {
  5. public final static String serverIP = "localhost";
  6. public final static int serverPort = 4347;
  7. public static String userName = null;
  8. public static void main(String[] args) {
  9. Socket client = null;
  10. BufferedReader sin = null;
  11. Writer cout = null;
  12. BufferedReader cin = null;
  13. try {
  14. /* 建立Socket连接 */
  15. client = new Socket(serverIP, serverPort);
  16. /* 从用户键盘读取输入 */
  17. sin = new BufferedReader(new InputStreamReader(System.in));
  18. /* 写入数据到Socket中 */
  19. cout = new OutputStreamWriter(client.getOutputStream());
  20. /* 从Socket读取输入 */
  21. cin = new BufferedReader(new InputStreamReader(client.getInputStream()));
  22. /* 登陆 */
  23. System.out.print("Please login: ");
  24. userName = sin.readLine();
  25. /* 获取用户输入的一行,exit则退出 */
  26. String line;
  27. System.out.print("> ");
  28. line = sin.readLine();
  29. while (!line.equals("exit")) {
  30. /* 将用户输入发送给Server */
  31. cout.write("[" + userName + "]: " + line + "\n");
  32. /* 刷新输出流使Server马上收到用户输入 */
  33. cout.flush();
  34. /* 从Server读入输入并显示 */
  35. System.out.println(cin.readLine());
  36. /* 读取用户下一行输入 */
  37. System.out.print("> ");
  38. line = sin.readLine();
  39. }
  40. } catch (UnknownHostException e) {
  41. e.printStackTrace();
  42. } catch (IOException e) {
  43. e.printStackTrace();
  44. } finally {
  45. /* 安全关闭输入输出和Socket */
  46. try {
  47. cout.close();
  48. cin.close();
  49. client.close();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. }
  1. /* TCPEchoServer.java */
  2. import java.io.*;
  3. import java.net.*;
  4. import java.util.Date;
  5. import java.lang.System;
  6. import java.lang.Thread;
  7. import java.lang.Runnable;
  8. public class TCPEchoServer {
  9. public final static int serverPort = 4347;
  10. public static int count = 0;
  11. @SuppressWarnings({"resource"})
  12. public static void main(String[] args) {
  13. ServerSocket server = null;
  14. Socket connection = null;
  15. try {
  16. /* 创建一个ServerSocket监听端口 */
  17. server = new ServerSocket(serverPort);
  18. System.out.println("Server start running...");
  19. while (true) {
  20. /* accept()阻塞等待客户返回Socket */
  21. connection = server.accept();
  22. System.out.println("Socket " + count + " established...");
  23. /* 创建一个线程与该用户交互 */
  24. Thread workThread = new Thread(new Handler(connection, count++));
  25. workThread.start();
  26. }
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. public static class Handler implements Runnable {
  32. private Socket socket = null;
  33. private int index = -1;
  34. public Handler(Socket _socket, int _index) {
  35. this.socket = _socket;
  36. this.index = _index;
  37. }
  38. public void run() {
  39. BufferedReader cin = null;
  40. Writer cout = null;
  41. try {
  42. /* 从Socket读取输入 */
  43. cin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
  44. /* 写入数据到Socket中 */
  45. cout = new OutputStreamWriter(socket.getOutputStream());
  46. String line;
  47. /* 当Socket连接正常时 */
  48. while (socket.isConnected() && !socket.isClosed()) {
  49. /* 当阻塞成功获取用户输入时 */
  50. line = cin.readLine();
  51. /* 获取当前系统时间 */
  52. Date currentTime = new Date();
  53. String echo = currentTime.toString().split(" ")[3] + " " + line;
  54. /* 打印系统日志记录用户输入 */
  55. System.out.println(echo);
  56. /* 发送数据给用户 */
  57. cout.write(echo + '\n');
  58. /* 刷新输出流使用户马上收到消息 */
  59. cout.flush();
  60. }
  61. } catch (SocketException e) {
  62. // do nothing
  63. } catch (Exception e) {
  64. e.printStackTrace();
  65. } finally {
  66. try {
  67. /* 安全关闭输入输出和Socket */
  68. if (socket != null) {
  69. cout.close();
  70. cin.close();
  71. socket.close();
  72. }
  73. } catch (IOException e) {
  74. e.printStackTrace();
  75. }
  76. System.out.println("Socket " + index + " exit...");
  77. }
  78. }
  79. }
  80. }
  1. /* Makefile */
  2. target:
  3. javac -encoding utf-8 TCPEchoClient.java
  4. javac -encoding utf-8 TCPEchoServer.java
  5. javac -encoding utf-8
  6. run-TCPEchoClient:
  7. java TCPEchoClient
  8. run-TCPEchoServer:
  9. java TCPEchoServer
  10. clean:
  11. rm *.class

运行截图

问题解决方案

  1. 中文编码问题:在代码使用UTF-8编码并且编译选项添加UTF8参数的话,不需要在代码中声明为UTF8编码,使用了反而会出错,亲测。
  2. 面向连接的传输TCP:由于需要面向连接,因此一个服务端需要和多个客户端进行通信,这就需要在服务端使用多线程技术,一个客户端分配一个线程,分别处理不同客户端的通信。
  3. 面向无连接的传输UDP:由于不需要连接,也不在意可靠传输,因此当客户端发送了一个数据包之后,若一定时间内没有返回内容,可以认为传输失败,让用户接着输入下一个内容。
  4. 关于TCP的聊天室:在客户端中无法体现出一个聊天室的完成功能,但是服务端是体现出来了,如果需要在客户端也有这个体现,需要做线程之间的通信,想想还是太麻烦我就没做了。
  5. 还有一点是面向连接的程序,不应该每发送一次就连接一次再断开连接,这样子的通信效率太低,而是应该等到客户端退出后再断开连接,这点已实现。

样例代码下载

传送门:下载

Java实现TCP之Echo客户端和服务端的更多相关文章

  1. Java实现UDP之Echo客户端和服务端

    Java实现UDP之Echo客户端和服务端 代码内容 采用UDP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...

  2. 二、网络编程-socket之TCP协议开发客户端和服务端通信

    知识点:之前讲的udp协议传输数据是不安全的,不可靠不稳定的,tcp协议传输数据安全可靠,因为它们的通讯机制是不一样的.udp是用户数据报传输,也就是直接丢一个数据包给另外一个程序,就好比寄信给别人, ...

  3. java Socket Tcp示例三则(服务端处理数据、上传文件)

    示例一: package cn.itcast.net.p5.tcptest; import java.io.BufferedReader;import java.io.IOException;impo ...

  4. 在Java中使用Socket模拟客户端和服务端(多线程)

    1:Socket与ServerSocket的交互 2.Socket和ServerSocket介绍 Socket 构造函数 Socket() Socket(InetAddress address, in ...

  5. c++ 网络编程(一)TCP/UDP windows/linux 下入门级socket通信 客户端与服务端交互代码

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9601511.html c++ 网络编程(一)TCP/UDP  入门级客户端与服务端交互代码 网 ...

  6. Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序

    演示TCP的传输的客户端和服务端的互访 需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息. 客户端: 1.建立Socket服务,指定要连接方朵和端口 2.获取Socket流中的输出流,将数 ...

  7. 实验09——java基于TCP实现客户端与服务端通信

    TCP通信         需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手        底层通过 流 发送数据 数据没有大小限制        可靠的传输机制 - 丢包重发 包的顺序的 ...

  8. java Socket通信,客户端与服务端相互发消息

    1.通信过程 网络分为应用层,http.ssh.telnet就是属于这一类,建立在传输层的基础上.其实就是定义了各自的编码解码格式,分层如下: 2.Socket连接 上述通信都要先在传输层有建立连接的 ...

  9. [Java]Hessian客户端和服务端代码例子

    简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...

随机推荐

  1. MFC ComboBox的使用

    前言 Combo Box (组合框)控件很简单,可以节省空间.从用户角度来看,这个控件是由一个文本输入控件和一个下拉菜单组成的.用户可以从一个预先定义的列表里选择一个选项,同时也可以直接在文本框里面输 ...

  2. 在python3.5中使用pip

    我centos7上同时有python2.7和python3.5.现在希望能在使用python3.5时也能用pip.本来这应该是很容易的一件事,然而我一步步掉进坑里.. 官网安装pip的方法是,http ...

  3. (笔记)angular 的根据后台StateCode本地显示指定文案

  4. Hive[1] 初识 及 安装

    本文前提是Hadoop & Java & mysql 数据库,已经安装配置好,并且 环境变量均已经配置到位   声明:本笔记参照 学习<Hive 编程指南>而来,如果有错误 ...

  5. Connect to a Windows PC from Ubuntu via Remote Desktop Connection

    http://www.7tutorials.com/connecting-windows-remote-desktop-ubuntu A useful feature of Windows is be ...

  6. http://www.shanghaihaocong.com-WORDPRESS开发的企业主题站

    wordpress是世界上使用最多的php开源博客系统,功能强大,而且拥有众多的插件,可扩展性强. 最近,我也用它做了一个企业网站,欢迎浏览:http://www.shanghaihaocong.co ...

  7. silverlight 退出当前页面、跳转到主页面

    1.退出当前页面 private void imgExit_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (Message ...

  8. NodeManager起不来

    NodeManager无法启动,解除授权,重新授权! CDH需要注意的表: SELECT * FROM `ROLES` SELECT * FROM CONFIGS WHERE attr LIKE '% ...

  9. Java实现计算20的阶乘

    循环从1乘到20,要注意的就是结果可能会很大,长度超出int类型的范围,所以定义乘积的时候用long. 代码如下: public class Practice3 { public static voi ...

  10. 通过JAVA代码获取手机的一些基本信息(本机号码,SDK版本,系统版本,手机型号)

    代码如下: package com.zzw.getPhoneInfos; import android.app.Activity; import android.content.Context; im ...