前几天介绍了计算机网络的一些概念,并介绍了几个协议。下面就说说 Java 中的 Socket 编程,服务器和客户端是如何通信的呢?

首先要介绍一下 Socket ,我们知道在 TCP/IP 协议簇中,TCP、UDP 协议都是在传输层,应用层基于传输层进行通信。而 Socket 可以看成是对 TCP 、UDP 协议的实现。具体到编程的时候,要看业务选择是使用 TCP 还是 UDP 协议。今天主要讲的就是基于 TCP 通信的 Socket 实现。若你对 TCP 还不熟悉。可以看这篇文章。

Java 中为 TCP 协议提供了两个类:Socket 类和 ServerSocket 类。一个 Socket 实例代表了 TCP 连接的一个客户端,而一个 ServerSocket 实例代表了 TCP 连接的一个服务器端,一般在 TCP Socket 编程中,客户端有多个,而服务器端只有一个,客户端 TCP 向服务器端 TCP 发送连接请求,服务器端的 ServerSocket 实例则监听来自客户端的 TCP 连接请求,并为每个请求创建新的 Socket 实例,由于服务端在调用 accept()等待客户端的连接请求时会阻塞,直到收到客户端发送的连接请求才会继续往下执行代码,因此要为每个 Socket 连接开启一个线程(这里就是多线程的应用啊)。服务器端要同时处理 ServerSocket 实例和 Socket 实例,而客户端只需要使用 Socket 实例。

另外,每个 Socket 实例会关联一个 InputStream 和 OutputStream 对象,我们通过将字节写入 Socket 的 OutputStream 来发送数据,并通过从 InputStream 来接收数据。

好吧,上面的描述可能有点懵,下面就来看一个 demo。使用 Socket 实现一个简单的交互,在服务器端使用多线程来处理请求。

客户端实现如下:

public class Client {
public static void main(String[] args) throws IOException {
Socket socket = null;
PrintWriter pw = null;
BufferedReader br = null;
try {
// 创建Socket对象,指明需要连接的服务器地址和端口
socket = new Socket("localhost", 6688); // 连接建立后,通过 Socket 输出流向服务器端发送请求信息
pw = new PrintWriter(socket.getOutputStream());
pw.write("Hello , server . I'm Client !");
pw.flush();
socket.shutdownOutput(); // 通过输入流获取服务器端返回的响应信息;
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while((info = br.readLine()) != null){
System.out.println("服务器返回信息: "+ info);
}
socket.shutdownInput(); ----后面的错误处理和关闭资源省略-----
}
}

服务器端实现如下:

public class Server {
public static void main(String[] args) throws IOException {
Socket socket = null;
try {
// 创建ServerSocket对象,绑定监听端口
ServerSocket serverSocket = new ServerSocket(6688);
while(true){
// 通过accept()方法监听客户端请求
socket =serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
serverThread.start();
}
}
}

线程具体实现如下:

public class ServerThread extends Thread {
Socket socket = null;
BufferedReader br = null;
PrintWriter pw = null; public ServerThread(Socket socket){
this.socket = socket;
} @Override
public void run() {
try {
// 连接建立后,通过输入流读取客户端发送的请求信息 msg
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuffer msg = new StringBuffer();
String info = null;
while((info = br.readLine()) != null){
msg.append(info);
}
System.out.println("服务器收到 [ "+ socket.getInetAddress()+" ] 的消息 [ " + msg+" ]");
socket.shutdownInput(); // 通过输出流向客户端发送相应信息
pw = new PrintWriter(socket.getOutputStream());
pw.write(" success !");
pw.flush();
socket.shutdownOutput();
}
}
}

总结一下 Socket TCP 中实战的步骤。

服务器端:

(1) 创建ServerSocket对象,绑定监听端口;
(2) 通过accept()方法监听客户端请求;
(3) 连接建立后,通过输入流读取客户端发送的请求信息;
(4) 通过输出流向客户端发送相应信息;

(5) 关闭响应资源。

客户端:

(1) 创建Socket对象,指明需要连接的服务器地址和端口;
(2) 连接建立后,通过输出流向服务器端发送请求信息;
(3) 通过输入流获取服务器端返回的响应信息;

(4) 关闭响应资源。

注意:

1 首先执行服务器端代码。

2 服务器端执行之后默认就一直在等待客户端的连接请求。

3 以上只是一个非常基础的案例,这只是 Socket 编程的冰山一角。

4 可以优化的地方还有很多,服务器端参数的优化,如,接受数据的缓冲区大小、等待客户端连接的最长时间、使用线程池处理请求等。

Socket 编程之 TCP 实现的更多相关文章

  1. Linux系统编程(35)—— socket编程之TCP服务器的并发处理

    我们知道,服务器通常是要同时服务多个客户端的,如果我们运行上一篇实现的server和client之后,再开一个终端运行client试试,新的client就不能能得到服务了.因为服务器之支持一个连接. ...

  2. Linux系统编程(33)—— socket编程之TCP程序的错误处理

    上一篇的例子不仅功能简单,而且简单到几乎没有什么错误处理,我们知道,系统调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面可以迅速得到故障信息. 为使错误处理的代码不影 ...

  3. Linux系统编程(34)—— socket编程之TCP服务器与客户端的交互

    前面几篇中实现的client每次运行只能从命令行读取一个字符串发给服务器,再从服务器收回来,现在我们把它改成交互式的,不断从终端接受用户输入并和server交互. /* client.c */ #in ...

  4. Linux系统编程(32)—— socket编程之TCP服务器与客户端

    TCP协议的客户端/服务器程序的一般流程 服务器调用socket().bind().listen()完成初始化后,调用accept()阻塞等待,处于监听端口的状态,客户端调用socket()初始化后, ...

  5. Linux系统编程(30)—— socket编程之TCP/IP协议

    在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别.就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样.计算机使用者意识到,计算机 ...

  6. socket编程之TCP/UDP

    目标: 1.编写TCP服务端客户端,实现客户端发送数据,服务端接收打印 2.采用OOP方式编写TCP服务端客户端,实现客户端发送数据,服务端添加时间戳,返回给客户端 3.采用OOP方式编写UDP服务端 ...

  7. linux socket编程之TCP与UDP

    转:http://blog.csdn.net/gaoxin1076/article/details/7262482 TCP/IP协议叫做传输控制/网际协议,又叫网络通信协议 TCP/IP虽然叫传输控制 ...

  8. Java Socket编程之TCP

    基于TCP的Socket通信: 服务器端: 创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口 调用accept()方法开始监听,等待客户端的连接 连接建立后,通过 ...

  9. C#编程 socket编程之tcp服务器端和客户端

    基于Tcp协议的Socket通讯类似于B/S架构,面向连接,但不同的是服务器端可以向客户端主动推送消息. 使用Tcp协议通讯需要具备以下几个条件: (1).建立一个套接字(Socket) (2).绑定 ...

随机推荐

  1. 即时新闻展示插件jQuery News Ticker,超级简单!

    有时候我们为了节省页面空间,会在页面明显处放一小条,用来展示比较重要的即时新闻,一般以轮播的形式出现.今天要介绍的jQuery News Ticker插件就是用来实现这个即时新闻展示功能的,效果图如下 ...

  2. HSL

    说明: HSL(H,S,L) 取值: H: Hue(色调).0(或360)表示红色,120表示绿色,240表示蓝色,也可取其他数值来指定颜色.取值为:0 - 360 S: Saturation(饱和度 ...

  3. mysql手工注入步骤

    1.一般用 '  "  ) 等符号来闭合,再用%23(即#)来注释后面语句. 2.查找数据库,先用order by n猜字段,再用union select 1,2,3 ...n%23来查询. ...

  4. numpy 矩阵操作

    numpy 对矩阵对角线.上三角.下三角以及它们所在位置索引的提取 import numpy as np a = np.random.randint(0,10,[5,5]) print(a) # c ...

  5. python初步学习-练习题

    1.实现1-100的所有的和 #!/usr/bin/env python #encoding:utf8 '''实现1-100的所有的和 1. 使用列表解析获取0-100的列表 2. 使用reduce内 ...

  6. html5 构造网页的新方式

    从 html 诞生至今,我们构建 html 页面的使用 html 元素好像并没有太多的进步.在构建 html 页面中,用的最多的是 div 标签.但是应用 div 标签构建 html 页面有一个问题, ...

  7. css 实现圆形头像

    1.方法一 直接设置img为圆形,这种情况下如果图片不是正方形,图片会被拉伸 <img class="circleImg" src="../img/photo/im ...

  8. 20165230 2017-2018-2 《Java程序设计》第5周学习总结

    20165230 2017-2018-2 <Java程序设计>第5周学习总结 教材学习内容总结 第七章 内部类与异常类 内部类与外嵌类 可以在类中定义另一个类,即内部类 包含内部类的类为内 ...

  9. SqlServer存储过程(增删改查)

    * IDENT_CURRENT 返回为任何会话和任何作用域中的特定表最后生成的标识值. CREATE PROCEDURE [dbo].[PR_NewsAffiche_AddNewsEntity] ( ...

  10. libevent简介和使用【转】

    转自:http://www.open-open.com/lib/view/open1386510630330.html libevent是一个基于事件触发的网络库,memcached底层也是使用lib ...