失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > socket实现网络通信

socket实现网络通信

时间:2018-09-28 21:25:30

相关推荐

socket实现网络通信

socket实现网络通信

1.1、网络通信的要素

通信双方的地址:

IP

端口号

例如:127.0.0.1:8080

网络通信的协议:

TCP/IP参考模型

总结:

网络编程中有两个问题

如何准确的定位到网络上的一台主机

找到主机之后如何进行通信

网络编程中的要素

IP和端口号(Port)

网络通信协议 UDP、TCP

1.2、IP

IP地址:InetAdress类

唯一定位一台网络上的计算机

127.0.0.1:本机IP(lochost)

IP地址分类

iPv4/ipv6

公网(互联网)-私网(局域网)

ADCD类地址

192.168.xxx.xxx组织内部专用

测试ip

import .InetAddress;import .UnknownHostException;//测试Ippublic class TextInetAdress {public static void main(String[] args) {try {//通过名字返回本机IPInetAddress inetAdress1 = InetAddress.getByName("127.0.0.1"); System.out.println(inetAdress1);//通过名字查询百度网IP地址InetAddress inetAdress2 = InetAddress.getByName("");System.out.println(inetAdress2);//通过名字返回本机IPInetAddress inetAdress3 = InetAddress.getByName("localhost"); System.out.println(inetAdress3);//通过名字返回本机IPInetAddress inetAdress4 = InetAddress.getLocalHost(); System.out.println(inetAdress4);//常用方法System.out.println(inetAdress2.getHostAddress());//规范的System.out.println(inetAdress2.getCanonicalHostName());System.out.println(inetAdress2.getHostName());} catch (UnknownHostException e) {e.printStackTrace();}}}

1.3、端口

端口表示计算机上的一个进程:

不同的进程有不同的端口号

TCP/UDP端口

单个协议下端口号不能冲突

端口分类:

共有端口 0-1023

HTTP : 80

HTTPS : 443

FTP : 21

Telent : 23

程序注册端口:-49151,分配给用户或者程序

Tomcat : 8080

MySQL : 3306

Oracle : 1521

import .InetSocketAddress;public class TextInetSocketAddress {public static void main(String[] args) {InetSocketAddress socketAddress1 = new InetSocketAddress("127.0.0.1", 8080);System.out.println(socketAddress1);InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);System.out.println(socketAddress2);}}

1.4、通信协议

TCP/IP协议簇

TCP:用户传输协议

UDP:用户数据报协议

TCP/UDP对比:

TCP

连接服务器

稳定

三次握手,四次挥手

客户端-服务器

传输完成,释放连接,效率低

UDP

不连接服务器

不稳定

无论另一端有无准备,都能发送

1.5、TCP

1.5.1、消息传输

客户端

连接服务器Socket

发送消息

import java.io.IOException;import java.io.OutputStream;import .InetAddress;import .Socket;//客户端public class TcpClientDemo1 {public static void main(String[] args) {Socket socket=null;OutputStream os=null;try {//要知道服务器的地址,端口号InetAddress serverIp = InetAddress.getByName("127.0.0.1");int port=9999;//创建一个socket链接socket = new Socket(serverIp,port);//发送消息I/O流os = socket.getOutputStream();os.write("你好,欢迎学习".getBytes());} catch (Exception e) {e.printStackTrace();}finally {if (os!=null)try {os.close();} catch (IOException e) {e.printStackTrace();}if (socket!=null)try {socket.close();} catch (IOException e) {e.printStackTrace();}}}}

服务器

建立服务的端口ServerSocket

等待用户的连接accept()

接受用户的消息

import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import .ServerSocket;import .Socket;//服务器端public class TcpSeverDemo2 {public static void main(String[] args) {ServerSocket serverSocket=null;Socket accept=null;InputStream is=null;ByteArrayOutputStream baos=null;try {//我得有一个地址serverSocket = new ServerSocket(9999);//等待客户端连接过来while (true) {accept = serverSocket.accept();//读取客户端的内容is = accept.getInputStream();//管道流baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024]; //创建一个缓冲区int len; //用来判断是否将缓冲区的字节读完,读完则值为-1while ((len = is.read(buffer)) != -1) {baos.write(buffer, 0, len);//从buffer中写出数据到baos写出长度0-len}System.out.println(baos.toString());}} catch (Exception e) {e.printStackTrace();}finally {//关闭流资源if(baos!=null)try {baos.close();} catch (IOException e) {e.printStackTrace();}if (is!=null)try {is.close();} catch (IOException e) {e.printStackTrace();}if (accept!=null)try {accept.close();} catch (IOException e) {e.printStackTrace();}if (serverSocket!=null)try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}

1.5.2、文件传输

客户端

读取文件

创建连接

发送文件

import java.io.*;import .InetAddress;import .Socket;//读文件发送public class TcpFileDemo01 {public static void main(String[] args) throws Exception {//1创建一个socket连接获取端口和地址Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),9000);//2获取一个输出流OutputStream os = socket.getOutputStream();//3读文件流FileInputStream fis = new FileInputStream(new File("zhushunsheng.jpg"));byte[] buffered=new byte[1024]; //自定义一个缓冲区int len; //用来判断是否将缓冲区的字节读完while ((len=fis.read(buffered))!=-1){os.write(buffered,0,len); //从buffer中写出数据到baos写出长度0-len}//通知服务器我已经结束了socket.shutdownOutput();//确认服务器接收完毕才能断开连接InputStream inputStream = socket.getInputStream();//String byte[]ByteArrayOutputStream baos=new ByteArrayOutputStream();byte[] buffer2=new byte[];int len2;while ((len2=inputStream.read(buffer2))!=-1){baos.write(buffer2,0,len2);}System.out.println(baos.toString());//4关闭资源baos.close();inputStream.close();fis.close();os.close();socket.close();​}}

服务器

创建连接

监听连接

接收文件

import java.io.*;import .ServerSocket;import .Socket;//接收文件public class TcpFileDemo02 {public static void main(String[] args) throws Exception {//1创建服务ServerSocket serverSocket = new ServerSocket(9000);//监听客户端的连接Socket accept = serverSocket.accept();//2获取输入流InputStream is = accept.getInputStream();//3输出文件FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));byte[] buffer=new byte[1024];int len;while ((len=is.read(buffer))!=-1){fos.write(buffer,0,len);}//通知客户端我接收完毕了OutputStream os=accept.getOutputStream();os.write("我接收完毕了,你可以断开了".getBytes());//4关闭资源fos.close();is.close();accept.close();serverSocket.close();}}

注意事项:

如果文件在源文件目录下可以采用相对路径找到文件(这里采用此方式),如果文件不在源目录下则应采用绝对路径传输

1.6、UDP

模拟客户端1给客户端2发送消息

客户端1

创建连接

创建一个包

确认发送对象

发送包

import .DatagramPacket;import .DatagramSocket;import .InetAddress;//UDP不需要连接服务器public class UdpClientDemo1 {public static void main(String[] args) throws Exception {//建立一个socketDatagramSocket socket=new DatagramSocket(9999);//DatagramSocket数据报套接字//建立一个包String msg="你好";//发送给谁InetAddress lochost=InetAddress.getByName("127.0.0.1");int port=9090;//参数分别为数据,数据的长度,发送的地址,端口号DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, lochost, port);//发送包socket.send(packet);//关闭流socket.close();}}

客户端2

开放端口

接受数据

关闭连接

import .DatagramPacket;import .DatagramSocket;//还是要等待客户端的连接public class UdpSeverDemo2 {public static void main(String[] args) throws Exception {//开放端口DatagramSocket socket=new DatagramSocket(9090);//接收数据byte[] buffer= new byte[1024];DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);//接收socket.receive(packet);//关闭连接socket.close();System.out.println(packet.getAddress().getHostAddress());System.out.println(new String(packet.getData(),0,packet.getLength()));}}

如果觉得《socket实现网络通信》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。