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

代码内容

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

代码实现

/* TCPEchoClient.java */
import java.io.*;
import java.net.*; public class TCPEchoClient {
public final static String serverIP = "localhost";
public final static int serverPort = 4347;
public static String userName = null; public static void main(String[] args) {
Socket client = null;
BufferedReader sin = null;
Writer cout = null;
BufferedReader cin = null;
try {
/* 建立Socket连接 */
client = new Socket(serverIP, serverPort);
/* 从用户键盘读取输入 */
sin = new BufferedReader(new InputStreamReader(System.in));
/* 写入数据到Socket中 */
cout = new OutputStreamWriter(client.getOutputStream());
/* 从Socket读取输入 */
cin = new BufferedReader(new InputStreamReader(client.getInputStream()));
/* 登陆 */
System.out.print("Please login: ");
userName = sin.readLine();
/* 获取用户输入的一行,exit则退出 */
String line;
System.out.print("> ");
line = sin.readLine();
while (!line.equals("exit")) {
/* 将用户输入发送给Server */
cout.write("[" + userName + "]: " + line + "\n");
/* 刷新输出流使Server马上收到用户输入 */
cout.flush();
/* 从Server读入输入并显示 */
System.out.println(cin.readLine());
/* 读取用户下一行输入 */
System.out.print("> ");
line = sin.readLine();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
/* 安全关闭输入输出和Socket */
try {
cout.close();
cin.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/* TCPEchoServer.java */
import java.io.*;
import java.net.*;
import java.util.Date;
import java.lang.System;
import java.lang.Thread;
import java.lang.Runnable; public class TCPEchoServer {
public final static int serverPort = 4347;
public static int count = 0; @SuppressWarnings({"resource"})
public static void main(String[] args) {
ServerSocket server = null;
Socket connection = null;
try {
/* 创建一个ServerSocket监听端口 */
server = new ServerSocket(serverPort);
System.out.println("Server start running...");
while (true) {
/* accept()阻塞等待客户返回Socket */
connection = server.accept();
System.out.println("Socket " + count + " established...");
/* 创建一个线程与该用户交互 */
Thread workThread = new Thread(new Handler(connection, count++));
workThread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
} public static class Handler implements Runnable {
private Socket socket = null;
private int index = -1; public Handler(Socket _socket, int _index) {
this.socket = _socket;
this.index = _index;
} public void run() {
BufferedReader cin = null;
Writer cout = null;
try {
/* 从Socket读取输入 */
cin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
/* 写入数据到Socket中 */
cout = new OutputStreamWriter(socket.getOutputStream());
String line;
/* 当Socket连接正常时 */
while (socket.isConnected() && !socket.isClosed()) {
/* 当阻塞成功获取用户输入时 */
line = cin.readLine();
/* 获取当前系统时间 */
Date currentTime = new Date();
String echo = currentTime.toString().split(" ")[3] + " " + line;
/* 打印系统日志记录用户输入 */
System.out.println(echo);
/* 发送数据给用户 */
cout.write(echo + '\n');
/* 刷新输出流使用户马上收到消息 */
cout.flush();
}
} catch (SocketException e) {
// do nothing
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
/* 安全关闭输入输出和Socket */
if (socket != null) {
cout.close();
cin.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Socket " + index + " exit...");
}
}
}
}
/* Makefile */
target:
javac -encoding utf-8 TCPEchoClient.java
javac -encoding utf-8 TCPEchoServer.java
javac -encoding utf-8 run-TCPEchoClient:
java TCPEchoClient run-TCPEchoServer:
java TCPEchoServer clean:
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. sqlserver on linux

    学习SQL Server从在Linux上安装开始 原创 2016-11-18 衡子 衡子hengzi 微软已经发布了SQL Server on Linux,目前支持Redhat和Ubuntu两种发行版 ...

  2. C#多线程案例基础

    C#多线程案例基础(转) 在学习多线程之前,我们先来看几个概念: 1,什么是进程?    当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,当然一个程序也可能开 ...

  3. 何时使用 Em 与 Rem

    原文  http://www.w3cplus.com/css/when-to-use-em-vs-rem.html   你可能已经很熟练使用这两个灵活的单位,但你可能不完全了解何时使用rem,何时使用 ...

  4. 【风马一族_php】NO0_搭建web服务器

    原文来自:http://www.cnblogs.com/sows/p/5977996.html  (博客园的)风马一族 侵犯版本,后果自负 安装apache apache是一种B/S结构的软件,apa ...

  5. C puzzles详解【38-45题】

    第三十八题 What is the bug in the following program? #include <stdlib.h> #include <stdio.h> # ...

  6. JSP ajax跨域问题 怎么处理 原因:CORS 头缺少 'Access-Control-Allow-Origin')。 ajax http 415

    /** * Project Name:cm2mManage * File Name:CrossSiteFilter.java * Package Name:com.yoxnet.serverframe ...

  7. jQuery实现动态添加和删除一个div

    本文主要给大家简单介绍一下如何动态的在一个元素添加和删除div,希望能够得到举一反三之效. 代码实例如下: <!DOCTYPE html> <html> <head> ...

  8. 《第一行代码--Android》阅读笔记之广播

    广播接收器 1.注册方式 动态注册:在程序中注册,如在Activity里的onCreate()方法中注册 静态注册:在AndroidManifest.xml中注册   2.可接收哪些广播 接收系统消息 ...

  9. linux常用命令--ps、netstat、find

     一.ps 1.1ps命令简介 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那 ...

  10. (转)浅谈HTML5与css3画饼图!

    神马系饼图? 饼图,大家都应该熟知,在统计数据对比方面,几乎处处用到.如cnzz的统计饼图 从饼图中,很形象地展示了访问者地区的分布,以扇形为块的方式拼成一个大圆. 都使用什么方法实现 目前众多站点制 ...