基于tcp和udp的socket实现

news/2024/7/2 23:17:02

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

 

 本文介绍如何用Java实现Socket编程。首先介绍Java针对Socket编程提供的类,以及它们之间的关系。然后分别针对TCP和UDP两种传输层协议实现Socket编程。

1 Java中的Socket编程接口介绍

Java为Socket编程封装了几个重要的类。

1.1 Socket类

Socket类实现了一个客户端socket,作为两台机器通信的终端,默认采用的传输层协议为TCP,是一个可靠传输的协议。Socket类除了构造函数返回一个socket外,还提供了connect, getOutputStream, getInputStream和close方法。connect方法用于请求一个socket连接,getOutputStream用于获得写socket的输出流,getInputStream用于获得读socket的输入流,close方法用于关闭一个流。

1.2 DatagramSocket类

DatagramSocket类实现了一个发送和接收数据报的socket,传输层协议使用UDP,不能保证数据报的可靠传输。DataGramSocket主要有send, receive和close三个方法。send用于发送一个数据报,Java提供了DatagramPacket对象用来表达一个数据报。receive用于接收一个数据报,调用该方法后,一直阻塞接收到直到数据报或者超时。close是关闭一个socket。

1.3 ServerSocket类

ServerSocket类实现了一个服务器socket,一个服务器socket等待客户端网络请求,然后基于这些请求执行操作,并返回给请求者一个结果。ServerSocket提供了bind、accept和close三个方法。bind方法为ServerSocket绑定一个IP地址和端口,并开始监听该端口。accept方法为ServerSocket接受请求并返回一个Socket对象,accept方法调用后,将一直阻塞直到有请求到达。close方法关闭一个ServerSocket对象。

1.4 SocketAddress

SocketAddress提供了一个socket地址,不关心传输层协议。这是一个虚类,由子类来具体实现功能、绑定传输协议。它提供了一个不可变的对象,被socket用来绑定、连接或者返回数值。

1.5 InetSocketAddress

InetSocketAddress实现了IP地址的SocketAddress,也就是有IP地址和端口号表达Socket地址。如果不制定具体的IP地址和端口号,那么IP地址默认为本机地址,端口号随机选择一个。

1.6. DatagramPacket

DatagramSocket是面向数据报socket通信的一个可选通道。数据报通道不是对网络数据报socket通信的完全抽象。socket通信的控制由DatagramSocket对象实现。DatagramPacket需要与DatagramSocket配合使用才能完成基于数据报的socket通信。

 2. 基于TCP的Socket编程

上面描述了Java对Socket编程提供的接口,本节介绍如何实现一个基于TCP连接的Socket通信。

下面例子是Server端等待从Client端接收一条消息,然后再给客户端发送一个消息。

服务器端首先实例化ServerSocket对象,然后为其绑定一个本机地址,并开始监听。一直阻塞状态下等待客户端请求,当获得客户端连接请求后,返回一个socket对象。然后用这个socket接收一条消息,并发送一条消息。代码如下:

复制代码

package server.socket.java;import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;public class SocketTcp {static private String TAG = "SocketTcp: ";public static void main(String[] args){try {ServerSocket server = new ServerSocket();SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10001);server.bind(address);System.out.println("==waiting for being connected...");Socket client = server.accept();System.out.println("==connected with " + client.getRemoteSocketAddress() );PrintWriter socketOut = new PrintWriter(client.getOutputStream());System.out.println("==waiting message from client...");byte buf[] = new byte[1024];if ( client.getInputStream().read(buf) > 0 ) {System.out.println("Receive Message: " + new String(buf));}System.out.println("==sending message to client...");String sendStr = "This is the message for client.";socketOut.write(sendStr);socketOut.flush();socketOut.close();client.close();server.close();} catch (IOException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();}}
}

复制代码

 

 客户端首先实例化一个socket对象,用这个对象连接服务器端。连接成功后,发送一条消息,然后等待接收一条消息。代码如下:

复制代码

package client.socket.java;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;public class SocketTcp {static private String TAG = "SocketTcp: ";public static void main(String[] args){try {final Socket socket = new Socket();SocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 10001);System.out.println("==connecting to server ...");socket.connect(address);PrintWriter socketOut = new PrintWriter(socket.getOutputStream());BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()) );String sendStr = "This is the message for server.";System.out.println("==sending message to server ...");socketOut.write(sendStr);socketOut.flush();System.out.println("==waiting message from server ...");String receiveStr = socketIn.readLine();System.out.println("Receive Message: " + receiveStr);socketOut.close();socketIn.close();socket.close();} catch (IOException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();} finally {}}
}

复制代码

 服务器端运行结果: 

==waiting for being connected...
==connected with /172.26.176.69:53912
==waiting message from client...
Receive Message: This is the message for server.

 客户端运行结果: 

==connecting to server ...
==sending message to server ...
==waiting message from server ...
Receive Message: This is the message for client.

 3 基于UDP的Socket编程示例

 基于UDP的Socket编程与基于TCP的socket编程稍有不同,socket server和client都用DatagramSocket实现。

 下面例子是Server端等待从Client端接收一条消息,然后再给客户端发送一个消息。

 服务器端首先实例化DatagramSocket对象,然后为其绑定一个本机地址,并开始监听。一直阻塞状态下等待从客户端接收数据报。然后从数据报中获取数据报的源地址,然后用这个源地址作为目的地址打包一个数据报,然后发送出去。代码如下:

复制代码

package server.socket.java;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;public class SocketUdp {final private static String TAG = "SocketUdp: ";public static void main(String args[]) {DatagramSocket socket = null;DatagramPacket datapacket = null;InetSocketAddress address = null;try {address = new InetSocketAddress(InetAddress.getLocalHost(), 7778);socket = new DatagramSocket(address);// socket.bind(address);byte buf[] = new byte[1024];datapacket = new DatagramPacket(buf, buf.length);System.out.println("==block for receive messages...");socket.receive(datapacket);buf = datapacket.getData();InetAddress addr = datapacket.getAddress();int port = datapacket.getPort();System.out.println("Message Content: " + new String(buf) );System.out.println("Receive From " + addr + ":" + port);SocketAddress toAddress = datapacket.getSocketAddress();String sendStr = "I'm Server, this is the message for client.";buf = sendStr.getBytes();datapacket = new DatagramPacket(buf, buf.length);datapacket.setSocketAddress(toAddress);socket.send(datapacket);System.out.println("==message sended");} catch (UnknownHostException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();} catch (SocketException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();} catch (IOException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();}}}

复制代码

  客户端首先实例化一个DatagramSocket对象。利用服务器地址和端口号作为目的地址打包一个数据报,并发送。然后等待从服务器回复的数据报。代码如下: 

复制代码

package client.socket.java;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;public class SocketUdp {final private static String TAG = "SocketUdp: ";public static void main(String args[]) {try {DatagramSocket getSocket = new DatagramSocket();DatagramPacket datapacket = null;InetSocketAddress toAddress = new InetSocketAddress(InetAddress.getLocalHost(), 7778);String sendStr = "I'm client, this is the message for server.";byte buf[] = sendStr.getBytes();datapacket = new DatagramPacket(buf, buf.length);datapacket.setSocketAddress(toAddress);getSocket.send(datapacket);System.out.println("==message sended");System.out.println("==block for receive messages...");getSocket.receive(datapacket);buf = datapacket.getData();System.out.println("Message Content: " + new String(buf));} catch (SocketException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();} catch (UnknownHostException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();} catch (IOException e) {System.out.println(TAG + e.getMessage());e.printStackTrace();}}
}

复制代码

 服务器端运行结果:

==block for receive messages...
Message Content: I'm client, this is the message for server.

 客户端运行结果:

==message sended
==block for receive messages...
Message Content: I'm Server, this is the message for client.

分类: 网络编程,Java学习笔记

好文要顶 关注我 收藏该文  

洪雁君
关注 - 7
粉丝 - 3

+加关注

0

0

« 上一篇:传输层中的TCP和UDP浅析
» 下一篇:长连接与短连接

posted on 2013-09-02 00:56 洪雁君 阅读(4109) 评论(0) 编辑 收藏

 

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请 登录 或 注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【活动】阿里云双11活动开始预热 云服务器限时2折起
【调查】有奖调研即刻参与,你竟然是酱紫程序猿!
【推荐】Vue.js 2.x 快速入门,大量高效实战示例

葡萄城

最新IT新闻:
· 《周鸿祎自传》书摘:首谈私有化,我从没想过退出
· 一个老外的自述:“在中国手机就是我的生命”
· PayPal CEO:未来5年内 金融科技变化将远超过去30年
· 快递员回应"月薪过万":送1件提成1元 双11可挣万元
· 微软收购动态图片应用程序Swng 团队加入Skype部门
» 更多新闻...

阿里云双11

最新知识库文章:

· 关于编程,你的练习是不是有效的?
· 改善程序员生活质量的 3+10 习惯
· NASA的10条代码编写原则
· 为什么你参加了那么多培训,却依然表现平平?
· 写给初学前端工程师的一封信

» 更多知识库文章...

Powered by: 
博客园 
Copyright © 洪雁君

<2017年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

导航

  • 博客园
  • 首页
  • 新随笔
  • 联系
  • 订阅订阅
  • 管理

统计

  • 随笔 - 27
  • 文章 - 1
  • 评论 - 1
  • 引用 - 0

公告

昵称:洪雁君
园龄:7年6个月
粉丝:3
关注:7

+加关注

搜索

 

 

常用链接

  • 我的随笔
  • 我的评论
  • 我的参与
  • 最新评论
  • 我的标签

我的标签

  • Linux学习笔记(3)
  • JavaScript(2)
  • OTT(1)
  • XMLHttpRequest(1)
  • 微信(1)

随笔分类

  • Java学习笔记(5)
  • Linux学习笔记(6)
  • NodeJS(1)
  • python学习笔记(1)
  • 调研报告(2)
  • 科技时评(1)
  • 网络编程(3)

随笔档案

  • 2014年6月 (1)
  • 2013年11月 (6)
  • 2013年10月 (2)
  • 2013年9月 (7)
  • 2013年8月 (5)
  • 2013年7月 (2)
  • 2013年6月 (1)
  • 2013年4月 (1)
  • 2013年1月 (2)

相册

  • blog配图(4)

最新评论

  • 1. Re:关于运营商向微信收费的所感
  • 赞同楼主的观点!
  • --刘江北

阅读排行榜

  • 1. FFserver服务器实现WebM格式视频直播(4234)
  • 2. 基于TCP和UDP的Socket实现(JAVA)(4109)
  • 3. JavaScript中XMLHttpRequest实现跨域访问(3722)
  • 4. Ubuntu通过apt-get安装Oracle JDK(1374)
  • 5. 云计算面试题集锦(1261)

推荐排行榜

  • 1. FFserver服务器实现WebM格式视频直播(1)

转载于:https://my.oschina.net/u/3644171/blog/1563945


http://lihuaxi.xjx100.cn/news/240417.html

相关文章

保护到云端的高速公路

如今&#xff0c;越来越多的业务和个人信息都存储在云计算中&#xff0c;因此&#xff0c;确保快速可靠地访问这些信息变得比以往任何时候都更加重要。电信服务提供商有强大的财政激励&#xff0c;提供一系列服务&#xff0c;可以与那些只能通过有线提供服务的厂商进行竞争。换…

c# 数据可视化_#OpenVisConf上的22位数据可视化从业者的10点收获

c# 数据可视化by Siena Duplan通过锡耶纳杜普兰(Siena Duplan) #OpenVisConf上的22位数据可视化从业者的10点收获 (10 Takeaways from 22 Data Visualization Practitioners at #OpenVisConf) Update | May 13, 2016: Videos of all talks are officially live!更新| 2016年5月…

开源可视化日志分析软件-Gource

Gource可以将代码版本控制系统里面的日志全部可视化&#xff0c;也就是说可以看见每个成员在系统里面提交代码的行为&#xff0c;Gource目前支持git、hg、svn。 静态的图片看着不过瘾&#xff0c;下面我将录频的效果(gourcegltail)给大家分享&#xff1a; http://www.tudou.com…

IDEA新建springboot项目发生错误

idea新建spring boot项目 选择这个默认的Default 之后弹出提示框如下 这个时候首先试一下更换一下网络&#xff0c;我用的是wifi就换成热点&#xff0c;就可以了&#xff0c;是因为网络的问题

贸易保护主义不能解决德国光伏企业的问题

针对德国媒体近期将该国光伏巨头SolarWorld宣布破产一事与中国相关联&#xff0c;甚至指责“中国盗走德国工作”的论调&#xff0c;中国驻德国大使馆经济商务参赞处公使衔参赞王卫东18日向记者表示&#xff0c;SolarWorld作为当初推动欧盟发起对华光伏产品“双反”措施的领头公…

了解ES6 The Dope Way Part II:Arrow功能和'this'关键字

by Mariya Diminsky通过玛丽亚迪明斯基(Mariya Diminsky) 了解ES6 The Dope Way Part II&#xff1a;Arrow功能和this关键字 (Learn ES6 The Dope Way Part II: Arrow functions and the ‘this’ keyword) Welcome to Part II of Learn ES6 The Dope Way, a series created t…

docker 基本操作Ⅲ

1 数据卷备份恢复 - 我们一般用的最多的是把容器和本地宿主机做目录映射直接存在本地&#xff0c;但是还有一种就是数据卷的备份与恢复&#xff0c;如下就来介绍&#xff1a; 先来一副图来了解一下数据卷的恢复与备份 宿主机也就是我们的服务器分享一个/data/backup/ 目录&…

怎样把字符1变成数字1

直接使用字符bai1减去字符0即可&#xff0c;如&#xff1a;‘1’-0’ 解释&#xff1a; 这样做可行是因为字符0到字符9在ascii编码时是连续的&#xff0c;字符0的ascii值是48&#xff0c;字符1的ascii值是49&#xff0c;其他数字字符依次往后排&#xff0c;而ascii值实际上就…