当前位置: 首页 > 编程日记 > 正文

基于tcp和udp的socket实现

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

相关文章:

mysql 5.7编译安装重启_mysql5.7源码编译安装

安装mysql前的准备&#xff1a;一、安装依赖的库&#xff1a;yum install gcc-c ncurses-devel perl-Data-Dumper python-devel openssl openssl-devel二、 安装cmake(因为mysql5.7的编译由cmake来实现)安装cmake&#xff1a;cd cmake-2.8.8/预编译和安装&#xff1a;./bootst…

公开课 | 详解CNN-pFSMN模型以及在语音识别中的应用

近年来&#xff0c;在深度学习技术的帮助下&#xff0c;语音识别取得了极大的进展&#xff0c;从实验室开始走向市场&#xff0c;走向实用化。基于语音识别技术的输入法、搜索和翻译等人机交互场景都有了广泛的应用。 Librispeech是当前衡量语音识别技术的最权威主流的开源数据…

属蛇人一生运势

一生总运势 巳年生人&#xff0c;其性稳和才智&#xff0c;好安排进退&#xff0c;甚喜交际。有高尚的品质&#xff0c;受朋友好评&#xff0c;但其内心常有阴毒与忌妒心&#xff0c;致难以保持永久交情&#xff0c;心情易造多疑之虑&#xff0c;而且好色&#xff0c;好与人争论…

mysql邮箱配置文件_SQL-数据库邮箱配置

一、启用数据库邮件手动启用数据库邮件功能&#xff0c;需执行以下脚本&#xff1a;exec sp_configure show advanced options,1RECONFIGUREexec sp_configure Database Mail XPs,1RECONFIGURE With Override二、配置数据库邮件1、启用配置向导如果事先没有手动启用数据库邮件功…

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

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

AI入侵机械设计,苦逼的“机械狗”还有未来吗?

作者 | Loren Grush译者 | 刘旭坤编辑 | 非主流出品 | AI科技大本营近几年&#xff0c;机械行业的平均薪资一直被 IT 碾压&#xff0c;更不用说 IT 行业里炙手可热的人工智能。现如今&#xff0c;AI 一路攻城略地&#xff0c;已经深入里很多行业和领域&#xff0c;其中就包括制…

[MySQL FAQ]系列 -- mysql是否支持跨库事务

作/译者&#xff1a;叶金荣&#xff08;Email: &#xff09;&#xff0c;来源&#xff1a;http://imysql.cn&#xff0c;转载请注明作/译者和出处&#xff0c;并且不能用于商业用途&#xff0c;违者必究。是可以支持的&#xff0c;例如这么用&#xff1a;start transaction; in…

docker 基本操作Ⅲ

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

jquery操作mysql_使用jQuery从数据库访问对象

[{“日期”:“2019-02-10”,“诉状”:1},{“日期”:“2019-02-12”,“诉状”:1},{“日期”:“2019-02-14”,“诉状”:1}]我可以通过Jquery代码轻松地访问它// AJAX Request to get the data by UserID and Week 1$.get(/dashboard/performance?name document.getElementById(…

中国AI专利申请量超美国,百度居国内首位

整理 | 非主流本文数据来自《人工智能技术专利深度分析报告》随着人工智能成为新一轮科技革命和产业变革的重要驱动力量&#xff0c;AI 成为科技企业研发重点&#xff0c;专利申请量也在逐年提升。中国专利保护协会近日发布的《人工智能技术专利深度分析报告》显示&#xff0c;…

MySQL数据库中文模糊检索问题

我在这里谈一下 MYSQL的中文模糊搜索。我的MYSQL版本。version()5.1.22-rc-community-log这里用到的表&#xff1a;Table Create Table ------ -------------------------------------------------------a1 CREATE TABLE a1…

最新Python学习项目Top10!

作者 | Mybridge译者 | Linstancy整理 | Jane出品 | AI科技大本营【导读】过去一个月里&#xff0c;我们对近1000个Python 学习项目进行了排名&#xff0c;并挑选出热度前10的项目。这份清单涵盖了包括Web App, Geospatial Data, Time Paradox, Testing in Python, Crash repor…

理解HTTP消息头【很完整,例子也很丰富】

&#xff08;一&#xff09;初识HTTP消息头 但凡搞WEB开发的人都离不开HTTP&#xff08;超文本传输协议&#xff09;&#xff0c;而要了解HTTP&#xff0c;除了HTML本身以外&#xff0c;还有一部分不可忽视的就是HTTP消息头。做过Socket编程的人都知道&#xff0c;当我们设计一…

css样式分类

1.内联式&#xff08;直接在标签里写属性&#xff0c;属性名为style&#xff09; 2.内嵌式 (直接嵌入到head标签里面&#xff0c;以标签形式出现&#xff0c;标签名为style&#xff09; 选择器&#xff1a;用来选择标签 1&#xff1a;用标签选择 2&#xff1a;用ID选择 关键符…

hadoop mysql mybatis_MyBatis简介与配置MyBatis+Spring+MySql

MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言…

MySQL中定义fk语句_MySQL基础篇/第3篇:MySQL基本操作语句.md · qwqoo/MySQL-Review - Gitee.com...

### 第3篇&#xff1a;MySQL基本操作语句- MySQL基础操作#### 排序检索数据- 之前的数据没有进行排序&#xff0c;其是按照默认在数据表中的数据返回的- SELECT语句的ORDER BY 子句进行排序mysql# 没有特定的顺序查询 (虽然结果看起来是有序的&#xff0c;是因为数据表中就是这…

如何高效推进ML模型开发和部署?Uber机器学习平台Michelangelo实践

作者 | Jeremy Hermann & Mike Del Balso 译者 | 王天宇 整理 | Jane 出品 | AI科技大本营 【导读】2017年9月&#xff0c;Uber 在技术社区发表了一篇文章向大家介绍了 Uber 的机器学习平台 —— Michelangelo。随着平台的日渐成熟&#xff0c;Uber 的业务数量与能力也随…

Api 函数: GetCursorPos 与转换

//获取鼠标在窗体中的当前位置 procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); varstr: string; beginstr : Format(%d,%d,[X,Y]);ShowMessage(str); end;//用 GetCursorPos 获取的是鼠标相对与屏幕的位置 varps:…

向下滚动页面导航悬浮

为什么80%的码农都做不了架构师&#xff1f;>>> 做两个导航&#xff0c;第二个隐藏 下拉到一定位置&#xff0c;显示第二个&#xff0c;position:fixed $(function(){$(window).scroll(function () {var top $(document).scrollTop();var m$(".nav")…

胜过iPhone XS?Google Pixel的“夜视功能”是怎样炼成的

作者 | Marc Levoy、Yael Pritch译者 | 刘旭坤整理 | Jane出品 | AI科技大本营【导读】随着智能手机的不断发展成熟&#xff0c;为了寻找差异化的厂商不断增加摄像头的数量。然而&#xff0c;摄像头的数量越多&#xff0c;就代表拍照的质量越好吗&#xff1f;Google Pixel 手机…

npm导入bootstrap_vue cli3.0如何通过npm引入jquery和bootstrap?

不建议通过npm的方式引入这两个东西&#xff0c;因为这两个东西本身就是打包好的&#xff0c;通过npm的方式过去&#xff0c;还得在webpack中排除掉&#xff0c;迂回。要用就直接在html中通过script和link标签引入。jQuery是时代的产物&#xff0c;如果要用到vue&#xff0c;那…

ABAP 一个隐藏 selection-screen block的实例

以下是一个演示如何通过 selection-screen 中的pushbutton来动态改变屏幕上的字段的显示状态的&#xff08;即显示或者隐藏&#xff09;。注意&#xff1a;显示 通过本示例可知selection-screen 中的 field 的显示状态都是 的&#xff0c;在程序中修改其属性 active 的值为 0 时…

python计算文件中字母出现次数_python – 计算文本文件中字母的频率

使用collections.Counter()&#xff1a;from collections import Counterwith open(file) as f:c Counter()for x in f:c Counter(x.strip())正如mgilson指出的那样,如果文件不是那么大,你可以简单地做&#xff1a;c Counter(f.read().strip())例&#xff1a;>>> c…

公开课报名 | 详解CNN-pFSMN模型以及在语音识别中的应用

近年来&#xff0c;在深度学习技术的帮助下&#xff0c;语音识别取得了极大的进展&#xff0c;从实验室开始走向市场&#xff0c;走向实用化。基于语音识别技术的输入法、搜索和翻译等人机交互场景都有了广泛的应用。Librispeech是当前衡量语音识别技术的最权威主流的开源数据集…

Ruby开发环境配置

一、 RoR IDE http://deadlock.netbeans.org/hudson/job/ruby/ 你可以从这个地方下载Ruby IDE专用版本的netbeans&#xff0c;只有30MB大小&#xff0c;速度比RadRails还快&#xff01;netbeans的RoR支持很强大&#xff0c;但也要注意两点&#xff1a; 1) 一定要用JDK6.0&am…

net localgroup 命令详解

http://www.jb51.net/article/24733.htm windows 核心安装中&#xff0c;关闭防火墙的命令 netsh advfirewall set allprofiles state off Hyper-v使用远程管理工具的相关设置&#xff1a; http://technet.microsoft.com/zh-cn/library/cc794756(vws.10).aspx 在SCVMM中添加Hyp…

ii 第七单元 访问网络共享文件系统

挂载网络文件系统 网络文件系统是由网络附加存储服务器通过网络向多个主机提供的一种文件系统 , 而不是由块设备 ( 例如硬盘驱动器 ) 提供的。客户端通过特殊的文件系统协议和格式访问远程存储 Linux 中有两种主要协议可用访问网络文件系统 : NFS 和CIFS 。 访问网络共享的三个…

最新机器学习开源项目Top10

作者 | Mybridge译者 | Linstancy整理 | Jane出品 | AI科技大本营【导读】过去一个月里&#xff0c;我们对近 1400 个机器学习项目进行了排名&#xff0c;并挑选出热度前 10 的项目。这份清单涵盖了包括 OpenAI 最新开发的 RND 算法、Uber 构建的第一个自然语言处理平台、由 Be…

linux批处理mysql数据库_使用批处理对MySQL进行数据批量操作

批处理是一种非交互式运行MySQL程序的方法&#xff0c;如同您在MySQL中使用的命令一样&#xff0c;你仍然将使用这些命令。为了实现批处理&#xff0c;您重定向一个文件到MySQL程序中&#xff0c;首先我们需要一个文本文件&#xff0c;这个文本文件包含有与我们在MySQL中输入的…

JDBC Driver常用连接方法列表

Microsoft SQL Server series (6.5, 7.x and 2000) and Sybase 10JDBC Name: jTDSURL: [url]http://jtds.sourceforge.net/[/url]Version: 0.5.1Download URL: [url]http://sourceforge.net/project/show...?group_id33291[/url]语法: Class.forName("net.sourceforge.jt…