首页
学习
活动
专区
工具
TVP
发布

听说你还不会Socket编程!

作者:zskingking

博客:https://www.jianshu.com/p/b04930d2b85e

上周我们描述了传输层协议TCP、UDP,但它们毕竟只是协议,看不见摸不着,那我们怎们通过TCP、和UDP进行实际传输呢?不用着急,等看完这篇文章你一定会明白的。

Socket概述

Socket中文意思为插座的意思,专业术语称之为套接字,它把TCP/IP封装成了调用接口供开发者调用,也就是说开发者可以通过调用Socket相关API来实现网络通讯。在Java中也存在Socket相关API,主要分为两个,分别是基于UDP传输协议的Socket和基于TCP传输协议的Socket,本篇文章会对基于这两种传输协议的Socket进行详细描述。

UDP Socket

通过上节的内容我们知道UDP是无连接的,只要提供对方的IP地址和端口号就能进行数据的传输,其中IP负责定位主机端口负责定位应用。知道了目标IP和目标端口号通过Java中的UDP Socket就能进行IO传输,我们来看一下具体的代码体现

分别启动发送方和接收方,我们来看一下打印结果

发送方:

接收方:

成功接收到消息,并打印出发送方IP和端口,下面我来个大家撸一遍步骤

发送方:

首先创建udp的socket服务

将需要发送的数据放在数据包DatagramSocket中,DatagramSocket会根据UDP协议对数据包、IP、端口号进行封装

通过udp的socket服务将数据包发送

最后将udp服务关闭

接收方:

创建udp的socket服务,并且明确自己的端口号

创建DatagramSocket用来解析数据接收到的数据包

将数据接收到数据包DatagramSocket中

通过DatagramSocket解析数据

关闭服务

整个UDP发送数据的流程就是这样

注意点:

为UDP是无连接的不可靠传输,所以接收方需要在发送方发送数据之前就启动,否则会接收不到数据,也就是说必须先运行UDPSocketReceive再运行UDPSocketSend。

聊天实例

把上面的例子进行一些小改动就可以实现聊天功能

在接收方方法写一个无限循环让其处于持续接收状态,发送发通过对键盘录入加回车进行消息的发送,并且两个端点都具备发送和接收功能。需要注意的是receive()会执行一个无限循环,所以receive()和send()必须位于不同线程,否则会导致无法发送消息从而也接收不到消息。

来看打印结果:

UDPSocket1

UDPSocket2

我在UDPSocket1 的控制台中输入了:“hello udp2”、在UDPSocket2 的控制台中输入了:“hello udp1”,接收内容和发送内容完全一致,一个简单的聊天功能就实现了,希望不熟悉的朋友也可以敲一遍代码练一遍。

TCP Socket

TCP基于client-server是面向连接的可靠传输,上篇文章我们也讲解了TCP安全传输机制,可谓是相当复杂,如果需要个人对TCP协议进行封装显然大多数开发者是很难实现的,所以Java也为开发者提供了基于TCP的Socket,不同于UDP,TCP Socket分为Socket和ServerSocket对应着client和server,下面我来用代码实现一个简单的TCP通讯功能:

客户端:

首先创建一个Socket和InetSocketAddress ,然后通过Socket的connect()方法进行连接,连接成功后可以获取到输出流,通过该输出流就可以向服务端传输数据。

服务端:

首先创建一个服务端Socket并明确端口号,通过accept()方法获取到链接过来的客户端Socket,从客户端Socket中获取输入流,最后由输入流读取客户端传输来的数据。

我们来看看服务端的打印结果:

成功接收到客户端发来的数据

注意点:

一个服务端是可以同时和多个客户端进行通信的,那么它是如何区分不同客户端呢?从上面代码我们可以看到,服务端首先通过accept()获取到客户端Socket,然后通过客户端的Socket获取的流进行通讯,这也让服务端得以区分每个客户端。

文件传输实例

流程:客户端上传一个文件到服务端,服务端收到文件后进行保存,保存成功后给客户端一个响应。

客户端代码

创建Socket并连接,读取本地文件输入流,将文件写入到服务端,写入成功后读取服务端返回的数据。

服务端代码

创建Socket并获取到客户端Socket和输入流,在F盘的tcp目录下创建一个文件,将从客户端读取到的数据输出到文件中,保存成功后给客户端返回''success''

这样我们就实现了一哥客户端上传文件的功能,还是比较简单的,希望大家也能够跟着代码敲一遍。

TCP Socket多线程应用

细心的同学可能已经发现,上面我们的实例中一个服务端只能接收一个客户端的一次请求,这显然是不符合实际的,那么如何使一个服务端同时服务多个客户端呢?接着撸代码

客户端1控制台

客户端2控制台

这样就可以实现一个服务端服务多个客户端

细心的同学可能又发现了,上面的写法是存在问题的,由于服务端始终都在主线程中处理请求,所以客户端的请求需要被服务端排队处理,举个例子:Client1对服务端进行了一次请求,服务端在响应Client1之前是不会接受其他请求的,显然这是不符合逻辑的,真正的服务器是要具备并发处理的。而多线程恰好能解决这个问题,我们来看修改之后的服务端代码

运行效果适合加线程之前是一样的,但这种方式效率更高。

本篇文章叙述了基于UDP和TCP的Socket,UDP是无连接的,所以UDP Socket在发送数据的时候只需要目标IP和端口即可发送。TCP是面向连接的并且是基于client-server模式,在传输数据前需要进行连接,可以通过多线程技术实现并发处理客户端请求。本篇文章内容还是比较简单的,希望大家能把文章中代码自己敲一遍,掌握Socket的同时也能让你自己UDP和TCP的理解更加深刻。

今日问题:

大家都买好过年回家的车票没有?

打卡格式:

打卡 X 天,答:xxx 。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190118B0636C00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券