java实现socket网络编程
1、网络编程原理:
网络编程两大步骤
一、如何定位网络上的一台或者多台主机:
网络层主要负责网路主机的定位,数据传输传输的路由,由ip地址可以唯一的确定internet上的一台主机。
二、如何在定位之后进行数据的传输;
在传输层则提供面向应用的可靠(TCP)或者非可靠(UDP)的数据传输机制
对于客户端/服务器(C/S)结构。 即通信双方一方作为服务器等待客户提出请求并予以响应。
客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终运行,监听网络端口,
一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的
客户也能及时得到服务。
对于浏览器/服务器(B/S)结构。 客户则在需要服务时向服务器进行请求。服务器响应后及时返回,
不需要实时监听端口。
2、TCP协议与UDP协议
Tcp协议是一种面向链接的保证数据可靠传输的协议,得到的是一个顺序的无差错对的数据流,发送方和接收方创建socket连接的方式是,
服务端开启服务等待,等待客户端发送链接,创建链接后双方可进行发送或者接收操作。
UDP协议是一种无连接协议,每个数据包都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,
因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
3、什么是socket网络编程?
在网络编程中,网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
Socket套接字是通信的对象,它支持TCP/IP协议的网络通信。它是网络通信过程中端点的抽象表示,
包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,
远地进程的协议端口。
Socket本质是编程接口(API),对TCP/IP协议进行封装提供借口给程序员使用,这就是Socket编程接口;
4、java实现socket网络编程
服务端使用ServerSocket绑定IP和端口,使用Accept监听端口是否有客户端发送连接请求,一旦有客户端发送连接请求,
服务端就回送连接信息,正式建立连接。Server端和Client端都可以通过Send,Write等方法与对方通信。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
1、创建Socket;
2、打开连接到Socket的输入/出流;
3、按照一定的协议对Socket进行读/写操作;
4、关闭Socket。
5、代码实现
基于TCP的socket实现
服务端
public class TcpSocketServer {public static void main(String[] args) {try {// 创建服务端socket 绑定端口ServerSocket serverSocket = new ServerSocket();//绑定ipserverSocket = new ServerSocket(8088, 10, InetAddress.getByName("192.168.0.110"));// 创建客户端socket 用户下面接收客户端socket对象Socket socket = new Socket();System.out.println("等待客户端连接...");//循环监听等待客户端的连接while(true){// 监听客户端 没有接受到数据才会停在此处 接受到往下执行socket = serverSocket.accept();//发送内容实现线程的创建ServerThread thread = new ServerThread(socket); thread.start();//获取客户端的ipInetAddress address=socket.getInetAddress();System.out.println("当前链接的客户端的IP:"+address.getHostAddress());}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}
}}
服务端执行线程
public class ServerThread extends Thread{private Socket socket = null;public ServerThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {InputStream is=null;InputStreamReader isr=null;BufferedReader br=null;OutputStream os=null;
// * PW支持两个直接对文件写操作的构造方法:
// * PrintWriter(File f)传文件名
// * PrintWriter(String s)传路径
// * PrintWriter给人一种可以直接对文件进行操作的假象
// * PW是一个高级流
// * 实际上PW包装了字节流、字符流和字符缓冲流。
// * PW负责自动行刷新
// * bw负责提高效率
// * osw负责读字符
// * fos负责写字节
// * 最后PW能够按行很快地把一个字符串变成字节写在文件中PrintWriter pw=null;try {is = socket.getInputStream();isr = new InputStreamReader(is);br = new BufferedReader(isr);String info = null;while((info=br.readLine())!=null){System.out.println("客户端:"+info);}//非关闭连接 仅关闭一方的发送状况socket.shutdownInput();os = socket.getOutputStream();pw = new PrintWriter(os);pw.write("服务器欢迎你1");pw.flush();} catch (Exception e) {// TODO: handle exception} finally{//关闭资源try {if(pw!=null)pw.close();if(os!=null)os.close();if(br!=null)br.close();if(isr!=null)isr.close();if(is!=null)is.close();if(socket!=null)socket.close();} catch (IOException e) {e.printStackTrace();}}}
}
客户端
public class TcpSocketClient {public static void client() throws InterruptedException {try {// 和服务器创建连接Socket socket = new Socket("192.168.0.111", 8088);// 要发送给服务器的信息OutputStream os = socket.getOutputStream();PrintWriter pw = new PrintWriter(os);pw.write("订单状态以改变");//flush方法是用于将输出流缓冲的数据全部写到目的地。//所以一定要在关闭close之前进行flush处理,即使PrintWriter有自动的flush清空功能pw.flush();socket.shutdownOutput();// 从服务器接收的信息InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));String info = null;while ((info = br.readLine()) != null) {System.out.println("我是客户端,服务器返回信息:" + info);}br.close();is.close();os.close();pw.close();socket.close();} catch (Exception e) {e.printStackTrace();}}
}
在执行顺序上,如果先执行了客户端会直接请求,但是因为服务端还没有执行监听端口等待连接,客户端会出现连接异常或者超时
所以最好先执行服务端在执行客户端。
6、UDP实现
服务端:
public class UdpSocketServer {DatagramSocket socket = null;public static void main(String[] args) {try {// 要接收的报文byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes, bytes.length);// 创建socket并指定端口 ipInetSocketAddress isa = new InetSocketAddress("192.168.0.110", 8088);socket = new DatagramSocket(isa);// 接收socket客户端发送的数据while(true) {//如果没有收到会一致阻塞socket.receive(packet);String receiveMsg = new String(packet.getData(), 0, packet.getLength());System.out.println("消息长度" + packet.getLength());System.out.println("客户端:" + receiveMsg);msg=receiveMsg;}// 关闭socket
// socket.close();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}}
客户端
public class UdpSocketClient {public static void Client(String ip,String msg) {try {// 要发送的消息String sendMsg = msg;System.out.println(sendMsg);// 获取服务器的地址 得到本地主机地址InetAddress addr = InetAddress.getByName(ip);// 创建packet包对象,封装要发送的包数据和服务器地址和端口号DatagramPacket packet = new DatagramPacket(sendMsg.getBytes(),sendMsg.getBytes().length, addr, 8088);// 创建Socket对象DatagramSocket socket = new DatagramSocket();// 发送消息到服务器socket.send(packet);System.out.println("继续发送");// 关闭socketsocket.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
socket传输文件
因为TCP的可靠性这里选用Tcp进行传输,传输原理,连接建立后,客户端发送请求传输的文件名或者绝对路径+文件名到服务端,
服务端就会根据文件名或者绝对路径创建文件对象,判断文件是否存在,存在则以字节或者字符形式传输至客户端,客户端在指定目录保存
客户端:
public class FileTcpSocketClient {//image文件名public static void Imageclient(String image) throws InterruptedException {try {// 和服务器创建连接Socket socket = new Socket("192.168.0.106", 8089);// ===================发送给服务器的信息=================OutputStream os = socket.getOutputStream();PrintWriter pw = new PrintWriter(os);pw.write(image);//flush方法是用于将输出流缓冲的数据全部写到目的地。//所以一定要在关闭close之前进行flush处理,即使PrintWriter有自动的flush清空功能pw.flush();socket.shutdownOutput();// ========================从服务器接收文件====================InputStream is = socket.getInputStream();DataInputStream dis = new DataInputStream(is);FileOutputStream fos=null;//文件名String fileName = dis.readUTF();System.out.println("文件名"+fileName);//文件长度long fileLength = dis.readLong();System.out.println("文件大小"+fileLength);//下面三行是保存的路径 可以自己设置String staticPath = ClassUtils.getDefaultClassLoader().getResource("static/img").getPath();String path1=staticPath.substring(1, staticPath.length());System.out.println(path1);//指定保存目录 判断是否存在在 不存在则创建File directory = new File(path1);if(!directory.exists()) {directory.mkdir();}//与系统有关的默认名称分隔符。此字段被初始化为包含系统属性 file.separator 值的第一个字符。在 UNIX 系统上,此字段的值为 '/';在 Microsoft Windows 系统上,它为 '\'。//directory.getAbsolutePath() 获取指定目录绝对路径File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);if(!file.exists()) {fos = new FileOutputStream(file);// 开始接收文件byte[] bytes = new byte[1024];int length = 0;while ((length = dis.read(bytes, 0, bytes.length)) != -1) {fos.write(bytes, 0, length);fos.flush();}System.out.println("======== 文件接收成功 [File Name:" + fileName + "]");}is.close();os.close();pw.close();socket.close();} catch (Exception e) {e.printStackTrace();}}}
服务端:
public class FileTcpSocketServer extends Thread{@Overridepublic void run() {try {// 创建服务端socketServerSocket serverSocket = new ServerSocket(); //绑定ip 端口serverSocket.bind(new InetSocketAddress("192.168.0.106",8089));
// serverSocket = new ServerSocket(8089, 3, InetAddress.getByName("127.0.0.1"));// 创建客户端socketSocket socket = new Socket();System.out.println("等待客户端连接...");//循环监听等待客户端的连接while(true){// 监听客户端 没有接受到数据才会停在此处socket = serverSocket.accept();FileThread thread = new FileThread(socket);thread.start();//获取客户端的ipInetAddress address=socket.getInetAddress();System.out.println("当前链接的客户端的IP:"+address.getHostAddress());}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}
}
文件传输线程
public class FileThread extends Thread{private Socket socket = null;public FileThread(Socket socket) {this.socket = socket;}@Overridepublic void run() {InputStream is=null;InputStreamReader isr=null;BufferedReader br=null;OutputStream os=null;FileInputStream fis=null;DataOutputStream dos=null;String fileName=null;
// * PW支持两个直接对文件写操作的构造方法:
// * PrintWriter(File f)传文件名
// * PrintWriter(String s)传路径
// * PrintWriter给人一种可以直接对文件进行操作的假象
// * PW是一个高级流
// * 实际上PW包装了字节流、字符流和字符缓冲流。
// * PW负责自动行刷新
// * bw负责提高效率
// * osw负责读字符
// * fos负责写字节
// * 最后PW能够按行很快地把一个字符串变成字节写在文件中PrintWriter pw=null;try {is = socket.getInputStream();isr = new InputStreamReader(is);br = new BufferedReader(isr);String info = null;while((info=br.readLine())!=null){System.out.println("客户端:"+info);fileName=info;}//非关闭连接 仅关闭一方的发送状况socket.shutdownInput();os = socket.getOutputStream();pw = new PrintWriter(os);System.out.println(fileName);
//下面三行设置查找文件路径String staticPath = ClassUtils.getDefaultClassLoader().getResource("static/img").getPath();String path1=staticPath.substring(1, staticPath.length());System.out.println(path1+fileName);File file=new File(path1+fileName);String responseMsg="请求的文件不存在";System.out.println("7");if(!file.exists()){System.out.println("不存在");pw.write(responseMsg);pw.flush();}else {System.out.println("存在");fis = new FileInputStream(file);// 文件名和长度dos = new DataOutputStream(os);dos.writeUTF(file.getName());dos.flush();dos.writeLong(file.length());System.out.println(file.length());dos.flush();// 开始传输文件System.out.println("======== 开始传输文件 ========");byte[] bytes = new byte[1024];int length = 0;long progress = 0;while ((length = fis.read(bytes, 0, bytes.length)) != -1) {dos.write(bytes, 0, length);dos.flush();progress += length;System.out.print("| " + (100 * progress / file.length()) + "% |");}System.out.println();System.out.println("======== 文件传输成功 ========");}} catch (Exception e) {// TODO: handle exception} finally{//关闭资源try {if(pw!=null)pw.close();if(os!=null)os.close();if(br!=null)br.close();if(isr!=null)isr.close();if(is!=null)is.close();if(socket!=null)socket.close();} catch (IOException e) {e.printStackTrace();}}}}
java实现socket网络编程相关推荐
- Java之socket网络编程
socket网络编程 文章目录 socket网络编程 一.网络编程概述 二.网络通信要素概述 三.IP和端口号 四.网络协议 五.TCP网络编程 六.UDP网络编程 一.网络编程概述 网络编程的目的 ...
- 【Java】Socket网络编程解读与实战
Socket原理 Socket原理 <Socket 到底是什么> Socket--套接字 是网络应用程序编程的接口和一种机制 用套接字中的相关函数来建立连接和完成通信 Socket可以看成 ...
- (Java)socket网络编程及处理socket粘包拆包问题
目录 1.socket简介 2.TCP/IP协议 3.tcp三次握手 4.socket的一些接口函数原理 5.java socket 长连接粘包拆包问题 6.socket模拟服务端客户端发消息 7.U ...
- JAVA.SE Socket网络编程
文章目录 1.网络编程入门 1.1软件架构介绍 1.2互联网通信协议 1.3网络编程的三要素 2.TCP通信 2.1通信分为客户端与服务器 2.2 socket的介绍与使用 2.3servletSoc ...
- java使用socket网络编程实现qq互聊(UPD简单版本)
JAVA初学者.勿喷. eclipse稍微有点难用,关程序是在Console里面,要是没开出来并且死循环的话电脑cpu直接拉满了. 而且进程的关闭是输入指定的"再见"才关闭多线程, ...
- 【Java】Socket网络编程实现内网穿透、端口映射转发、内网穿透上网工具的编写,设置IP白名单防火墙
这里写目录标题 简介 更新 一.背景 1.1 情景假设 1.2 想要达到的目的 1.3 局限 1.3 解决方案一(路由器NAT) 1.4 解决方案二(云服务器转发) 二.方案介绍 2.1 方案简介 2 ...
- Java的Socket网络编程
1.Socket是什么? socket是进程之间通信的一种方式,调用这个网络库中的一些API实现分布在不同主机之间的相关进程的一些数据交换. 服务器端需要做的事情 打开一个通信通道并告诉本机,它愿意在 ...
- Java 之 socket 网络编程
客户端 import java.io.*; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.n ...
- Linux C++/Java/Web/OC Socket网络编程
一,Linux C++ Socket网络编程 1.什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制 ...
- linux java socket编程_深入学习socket网络编程,以java语言为例
了解java的socket编程与Linux Socket API之间的关系 一.java的网络编程 1.socket原理 socket通信就是通过IP和端口号将两台主机建立连接,提供通信.主机A的应用 ...
最新文章
- Ubuntu 12.04安装firefox 26中的flash plugin方法
- 新物流三大趋势!阿里研究院院长说一个空前机会来了
- Lucene.Net无障碍学习和使用:搜索篇
- Dagger2从入门到熟练
- jmeter设置全局变量
- C语言怎样编程分子变化,C语言经典编程(一)
- Redis 常用命令学四:集合类型命令
- iOS - Masonry自动布局
- textview 结束后释放_等待按键释放,你的代码如何写?
- 滑雪(信息学奥赛一本通-T1280)
- arm架构linux运行docker失败,armdocker:在x86上模拟运行arm容器
- MongoDB聚合(二)
- C语言的输出对齐应用
- 【转】word 高效经典教程
- phpstudy以及DVWA安装使用
- ABAP 关于 delete adjacent duplicates from的小心得
- 基于Vue.js模拟酒店预订移动App
- 大话2口袋版不显示服务器,大话西游2新口袋版操作指引及常见问题说明
- 计算机里的word怎么重装,word能卸载重装吗 word卸载重装
- 【程序员面试】校招和社招的区别
热门文章
- 微信公众号发送模版消息 Java实现
- lisp 天正标高_建筑设计选择 CAD 和天正画图哪个更好?
- 电脑录屏用什么软件?录屏软件哪个好用?
- 日记 - idea中的中文注释出现乱码的解决方案
- SUMO交通流仿真实战
- Android NFC 标签读写读取快速开发教程 ( 整理来自 https://blog.csdn.net/wolfking0608/article/details/72675180 )
- laya ts fgui的list滚动列表设置
- 一些爱不释手的 Chrome 插件
- android 获取软件签名工具,获取Android应用签名的几种方式
- 超级终端连接华为交换机_win8系统教你实现用超级终端连接华为交换机的超详细图文教程...