基于Socket的Java网络编程
2013-08-04 12:38
615 查看
------- java学习型技术博客、期待与您交流 ----------
Java基础总结之基于Socket的Java网络编程
一、网络基础知识
在学习网络编程之前,需要了解一些网络知识,比如说网络模型,IP地址,通讯端口,通讯协议,其中要重点熟悉TCP和UDP通讯协议。
1,网络参考模型
![](https://img-blog.csdn.net/20130804120359734)
2,IP地址
所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址,它是网络中设备的标识。但由于数字不易记忆,可用主机名。
3,端口
端口(port)可以认为是计算机与外界通讯交流的出口。用于标识进程的逻辑地址,不同进程的标识。
4,传输协议UDP 和TCP(必须熟悉)
TCP(传输控制协议)
TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。其特点如下:
◆ 建立连接,形成传输数据的通道。
◆ 在连接中进行大数据量传输
◆ 通过三次握手完成连接,是可靠协议
◆ 因为必须建立连接,效率会稍低
UDP(用户数据报协议)
UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。其特点如下:
◆ 将数据及源和目的封装成数据包中,不需要建立连接
◆ 每个数据报的大小在限制在64k内
◆ 因没有建立连接,是不可靠协议
◆ 也是因为不需要建立连接,所以速度较快
两者应用分析:
1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。
2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。
二、基于Socket的Java网络编程
1,什么是Socket?
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。通过网络进行通信的两端都有Socket,网络通信其实就是Socket之间的通信,也就是数据在两个Socket之间通过IO传输。
由于传输协议的不同,每个传输协议都有自己建立端点的方式,分别对UDP传输和TCP传输进行演示。
UDP传输
UDP传输需要以下几个步骤:
---->建立发送端,接收端。
---->建立数据包。
----> 调用Socket的发送接收方法(send(); receive();)。
----> 关闭Socket。
其中,发送端和接受端是两个独立的应用程序,在发送端,要在数据包对象中明确目的地IP及端口。在接收端,要指定监听的端口。
UDP传输示例:
需求:编写一个发送端程序,实现通过udp传输方式,将一段文字数据发送出去。用另一个接收端程序接受UDP协议传输的数据。
发送端:
接收端:
UDP练习:
需求:编写一个聊天程序。分为接收端和发送端,两端需要同时执行,所以需要运用多线程。一个线程负责发送数据,一个线程负责接收数据。由于收发的动作不一致,所以要定义两个run方法,且这两个方法要封装到不同的类中。代码如下:
TCP传输
UDP 传输分为发送端和接受端,而TCP传输则分为客户端和服务端,分别对应两个对象,Socket和ServerSocket。
◆ 客户端:
Socket对象在建立时,就可以去连接指定主机。因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
◆ 服务端:
Server端监听某个端口是否有连接请求,Client端向Server 端发出连接请求,Server端向Client端发回接受消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
TCP传输示例
需求:编写一个客户端程序,实现通过tcp传输方式,将一段文字数据发送出去。用另一个服务端程序接受tcp协议传输的数据。
客户端步骤:
1,创建Socket服务。并指定要连接的主机和端口。
2,由Socket对象得到输出流,并通过输出流的write方法写出数据
3,关闭客户端
服务端步骤:
1,建立服务端的socket服务。ServerSocket();并监听一个端口。
2,通过ServerSokcet的 accept方法,获取连接过来的客户端对象。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台。
4,关闭服务端。(可选)
TCP练习:
需求:模拟一个用户登录,客户端通过键盘录入用户名,服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登陆。并在客户端显示 xxx,欢迎光临。
如果该用户不存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。
最多登录三次。
------- java学习型技术博客、期待与您交流 ----------
Java基础总结之基于Socket的Java网络编程
一、网络基础知识
在学习网络编程之前,需要了解一些网络知识,比如说网络模型,IP地址,通讯端口,通讯协议,其中要重点熟悉TCP和UDP通讯协议。
1,网络参考模型
2,IP地址
所谓IP地址就是给每个连接在Internet上的主机分配的一个32bit地址,它是网络中设备的标识。但由于数字不易记忆,可用主机名。
3,端口
端口(port)可以认为是计算机与外界通讯交流的出口。用于标识进程的逻辑地址,不同进程的标识。
4,传输协议UDP 和TCP(必须熟悉)
TCP(传输控制协议)
TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。其特点如下:
◆ 建立连接,形成传输数据的通道。
◆ 在连接中进行大数据量传输
◆ 通过三次握手完成连接,是可靠协议
◆ 因为必须建立连接,效率会稍低
UDP(用户数据报协议)
UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。其特点如下:
◆ 将数据及源和目的封装成数据包中,不需要建立连接
◆ 每个数据报的大小在限制在64k内
◆ 因没有建立连接,是不可靠协议
◆ 也是因为不需要建立连接,所以速度较快
两者应用分析:
1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。
2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。
二、基于Socket的Java网络编程
1,什么是Socket?
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。通过网络进行通信的两端都有Socket,网络通信其实就是Socket之间的通信,也就是数据在两个Socket之间通过IO传输。
由于传输协议的不同,每个传输协议都有自己建立端点的方式,分别对UDP传输和TCP传输进行演示。
UDP传输
UDP传输需要以下几个步骤:
---->建立发送端,接收端。
---->建立数据包。
----> 调用Socket的发送接收方法(send(); receive();)。
----> 关闭Socket。
其中,发送端和接受端是两个独立的应用程序,在发送端,要在数据包对象中明确目的地IP及端口。在接收端,要指定监听的端口。
UDP传输示例:
需求:编写一个发送端程序,实现通过udp传输方式,将一段文字数据发送出去。用另一个接收端程序接受UDP协议传输的数据。
发送端:
class UdpSend { public static void main(String[] args) throws Exception { //1,通过DatagramSocket对象创建udp服务,并指定端口。 DatagramSocket ds = new DatagramSocket(8888); //2,确定数据,并封装成数据包。 byte[] buf = "udp ge men lai le ".getBytes(); DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),10000); //3,通过socket服务,将已有的数据包发送出去。通过send方法。 ds.send(dp); //4,关闭资源。 ds.close(); } }
接收端:
class UdpRece { public static void main(String[] args) throws Exception { //1,创建udp socket,建立端点。 DatagramSocket ds = new DatagramSocket(10000); //2,定义数据包。用于存储数据。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length); //3,通过服务的receive方法将收到数据存入数据包中。 ds.receive(dp);//阻塞式方法。 //获取IP地址 String ip = dp.getAddress().getHostAddress(); //4,通过数据包的方法获取其中的数据。 String data = new String(dp.getData(),0,dp.getLength()); //获取端口 int port = dp.getPort(); //打印数据信息 System.out.println(ip+"::"+data+"::"+port); //5,关闭资源 ds.close(); } }
UDP练习:
需求:编写一个聊天程序。分为接收端和发送端,两端需要同时执行,所以需要运用多线程。一个线程负责发送数据,一个线程负责接收数据。由于收发的动作不一致,所以要定义两个run方法,且这两个方法要封装到不同的类中。代码如下:
import java.io.*; import java.net.*; //定义一个发送端Send类实现Runnable接口 class Send implements Runnable { //为了DatagramSocket作用于整个类中,创建一个静态成员变量 private DatagramSocket ds; //以DatagramSocket对象为参数的构造函数 public Send(DatagramSocket ds) { this.ds = ds; } //覆盖Runnable接口的run方法 public void run() { try { //由系统标准输入设备构造BufferedReader对象,读取键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null) { //将读取到的数据存入字节数组中 byte[] buf = line.getBytes(); //将数据中的数据封装成数据报包 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.104"),10002); //通过DatagramSocket对象的send方法将读取到的数据发送出去。 ds.send(dp); //如果输入886则结束 if("886".equals(line)) break; } } catch (Exception e) { throw new RuntimeException("发送端失败"); } } } //定义一个接受端Send类实现Runnable接口 class Rece implements Runnable { private DatagramSocket ds; public Rece(DatagramSocket ds) { this.ds = ds; } public void run() { try { //由于接受端需要接受多个客户端发来的数据,所以将其置于循环中 while(true) { //创建一个缓冲区 byte[] buf = new byte[1024]; //定义一个数据报包存储接受到的数据 DatagramPacket dp = new DatagramPacket(buf,buf.length); //将接受的数据存入到数据包中 ds.receive(dp); //获取发送端IP地址 String ip = dp.getAddress().getHostAddress(); //获取发送端发送的数据 String data = new String(dp.getData(),0,dp.getLength()); //如果接受到的数据为"886"表面客户端离开,打印提示 if("886".equals(data)) { System.out.println(ip+"....离开聊天室"); break; } //打印发送端Ip和数据 System.out.println(ip+":"+data); } } catch (Exception e) { throw new RuntimeException("接收端失败"); } } } class ChatDemo { public static void main(String[] args) throws Exception { //创建发送端和接受端的Socket对象,(接收端要指定监听的端口) DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receSocket = new DatagramSocket(10002); //创建线程对象并开启 new Thread(new Send(sendSocket)).start(); new Thread(new Rece(receSocket)).start(); } }
TCP传输
UDP 传输分为发送端和接受端,而TCP传输则分为客户端和服务端,分别对应两个对象,Socket和ServerSocket。
◆ 客户端:
Socket对象在建立时,就可以去连接指定主机。因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功。形成通路后,在该通道进行数据的传输。
◆ 服务端:
Server端监听某个端口是否有连接请求,Client端向Server 端发出连接请求,Server端向Client端发回接受消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。
TCP传输示例
需求:编写一个客户端程序,实现通过tcp传输方式,将一段文字数据发送出去。用另一个服务端程序接受tcp协议传输的数据。
客户端步骤:
1,创建Socket服务。并指定要连接的主机和端口。
2,由Socket对象得到输出流,并通过输出流的write方法写出数据
3,关闭客户端
import java.io.*; import java.net.*; class TcpClient { public static void main(String[] args) throws Exception { //创建客户端的socket服务。指定目的主机和端口 Socket s = new Socket("192.168.1.254",10003); //由Socket对象得到输出流,并通过输出流的write方法写出数据 OutputStream out = s.getOutputStream(); out.write("This Message from tcpClient".getBytes()); s.close(); } }
服务端步骤:
1,建立服务端的socket服务。ServerSocket();并监听一个端口。
2,通过ServerSokcet的 accept方法,获取连接过来的客户端对象。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台。
4,关闭服务端。(可选)
class TcpServer { public static void main(String[] args) throws Exception { //建立服务端socket服务。并监听一个端口。 ServerSocket ss = new ServerSocket(10003); //通过accept方法获取连接过来的客户端对象。(此方法为阻塞式,没有连接就会等) while(true) { Socket s = ss.accept(); //获取客户端的IP地址 String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //获取客户端发送过来的数据,由Socket对象得到输入流。 InputStream in = s.getInputStream(); //定义数组缓冲读取到的数据 byte[] buf = new byte[1024]; int len = in.read(buf); //打印数组中的数据 System.out.println(new String(buf,0,len)); s.close();//关闭客户端. } //ss.close(); } }
TCP练习:
需求:模拟一个用户登录,客户端通过键盘录入用户名,服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登陆。并在客户端显示 xxx,欢迎光临。
如果该用户不存在,在服务端显示xxx,尝试登陆。并在客户端显示 xxx,该用户不存在。
最多登录三次。
import java.io.*; import java.net.*; //客户端 class LoginClient { public static void main(String[] args) throws Exception { //创建Socket服务。并指定要连接的主机和端口。 Socket s = new Socket("192.168.1.254",10008); //构造BufferedReader对象获取键盘录入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); //由Socket对象得到输出流,并构造PrintWriter对象 PrintWriter out = new PrintWriter(s.getOutputStream(),true); //由Socket对象得到输入流,并构造相应的BufferedReader对象 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //通过for循环限定次数 for(int x=0; x<3; x++) { //读取键盘录入信息 String line = bufr.readLine(); //如果客户端录入为空,例如“ctrl+c”退出。则结束循环 if(line==null) break; out.println(line); //读取服务端反馈信息并打印 String info = bufIn.readLine(); System.out.println("info:"+info); //如果服务端的反馈信息中包含“欢迎”表面登陆成功,跳出循环 if(info.contains("欢迎")) break; } //关闭流对象和客服端 bufr.close(); s.close(); } } //创建线程封装服务端针对多个客户端的校验代码 class UserThread implements Runnable { private Socket s; UserThread(Socket s) { this.s = s; } public void run() { //获取客户端IP并打印 String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"....connected"); try { //通过for循环控制次数 for(int x=0; x<3; x++) { //由Socket对象得到输入流,并构造相应的BufferedReader对象 BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream())); //读取客户端提交的数据 String name = bufIn.readLine(); //如果数据已经为空,则结束循环,(否则将以null为读取的到的数据进行无意义的判断) if(name==null) break; //构造BufferedReader对象并关联存储用户名的文件对象。 BufferedReader bufr = new BufferedReader(new FileReader("user.txt")); PrintWriter out = new PrintWriter(s.getOutputStream(),true); String line = null; //定义一个标记记录校验结果,默认为false boolean flag = false; while((line=bufr.readLine())!=null) { //如果匹配成功则结束循环并将标记置为true if(line.equals(name)) { flag = true; break; } } //根据标记在服务端输出相应提示,并向客户端写出相应提示。 if(flag) { System.out.println(name+",已登录"); out.println(name+",欢迎光临"); //标记为true则结束三次校验循环 break; } else { System.out.println(name+",尝试登录"); out.println(name+",用户名不存在"); } } //关闭客户端 s.close(); } catch (Exception e) { throw new RuntimeException(ip+"校验失败"); } } } //服务端 class LoginServer { public static void main(String[] args) throws Exception { //创建服务端SercerSocket对象,并监听端口 ServerSocket ss = new ServerSocket(10008); //由于可能存在多个客户端,使用while循环 while(true) { //通过accept方法获取连接过来的客户端对象 Socket s = ss.accept(); //创建用户线程并开启 new Thread(new UserThread(s)).start(); } } }
------- java学习型技术博客、期待与您交流 ----------
相关文章推荐
- 基于Socket(套接字)的低层次Java网络编程
- 基于Socket的JAVA网络编程
- 基于Socket的Java网络编程集粹
- 基于Socket的java网络编程
- java进阶 ------ 基于Socket低层次网络编程
- 基于Socket的java网络编程
- java网络编程【2】 基于Socket的java网络编程(含实例)
- java 基于socket套接字的低层次网络编程
- Java网络编程实践和总结 --- 基于TCP的Socket编程之echo回显的操作
- java进阶 ------ 基于Socket低层次网络编程
- java网络编程【2】 基于Socket的java网络编程(含实例)
- 基于Socket的Java网络编程集粹
- 基于Socket的Java网络编程集粹
- Java——多人聊天室(基于TCP的网络编程——Socket)
- 基于Socket的java网络编程
- 基于Socket的java网络编程
- Java网络编程基础(二)-- 基于TCP/IP的Socket编程
- Java网络编程(基于TCP的socket编程)
- java:网络编程(一/基于Socket的单客户端连接)
- 基于Socket的Java网络编程集粹