Socket网络编程

Socket网络编程

本文将简述计算机网络中IP地址、端口号、资源定位符、数据传输、客户端和服务器的常用模式等概念,与使用套接字编程及url类的常规用法。
在这里插入图片描述

一、计算机网络概念

网络:计算机网络是位于不同位置的若干台计算机使用传输介质连接起来,通过传输协议,
实现数据传输和资源共享。

二、Ip地址

计算机网络通过ip唯一区分处于网络中的一台计算机。

三、端口号

计算机中通过端口号来区分软件,端口号在计算中占两个自己,取值范围:0—65535
1、1024以下的端口通常是计算机内置软件端口,类似现实生活中的电话号码120 110
2、1024以上的,我们可以自定义,为了避免重复性,端口号定义的越大越好。
3、使用同种协议的软件之间,端口号不可重复;不同协议,端口号可以重复

四、资源定位

URL统一资源定位符 http://127.0.0.1:80/stusystem/user/1
URI 统一资源修饰符 user/1

五、数据的传输

1、计算机底层通过二进制数据进行通讯。通讯时如识别有效数据,还需不同的协议才能完成。常见的底层协议TCP/IP、 UDP
TCP/IP:类似于打电话,是一种面向连接的协议。特点是安全可靠,效率相对于UDP而言,较为低下。通讯模式为请求响应模式。
UDP:类似于发短信,是一种面向无连接的协议。特点是不可靠,安全性低,但效率高。
UDP是以数据为中心的协议。
2、数据在进行传输时,需要经过一系列的封装和拆分的过程。
(1) 数据的封装
(2) 数据的拆分
采用分层思想,完成对层次的解耦,以及各层的职责分离,让各层合理分工-----OSI七层模型。

六、客户端和服务器

C/S client/Server (胖客户端) 需要安装,需要更新
B/S Browser/Server(瘦客户端) 不需要安装,也不需要更新,服务器更新之后,打开浏览器,自动更新

七、传输层的传输方式

需要解决的问题:OSI七层模型中的二进制数,如何才能到达我们的应用软件
传输层的作用建立一个数据传输通道,将来自于OSI七层模式中的下三层的数据,传输到应用程序中。
这个数据传输通道,我们称之为Socket套接字,类似于现实生活中的传送履带。不过可以双向传输。
作为传输层来讲,只有两种协议:TCP/IP、UDP协议
TCP/IP协议在进行数据传输时,经过3次握手,4次挥手的过程。

TCP

客户端
1、 创建客户端并与服务器建立连接
2、 获取来自服务器的数据

package com.gezhi.net.tcp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客户端类
 * @author Administrator
 *
 */
public class Client {

	public static void main(String[] args) {
		
		BufferedReader reader = null;
		BufferedWriter out = null;
		try {
			//与服务器建立连接
			Socket client = new Socket("127.0.0.1", 80);
			String info = "需要系统资源,请发送给我";
			out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
			out.write(info);
			out.newLine();
			out.flush();
			
			//获取来自于服务器的数据
			reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
			String msg = reader.readLine();//一行一行的读取数据(阻塞式方法)
			System.out.println(msg);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				out.close();
				reader.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
		
		
		
	}
}

服务器
1、 创建服务器端 ServerSocket 类+端口
2、 侦听端口,接收来自该端口进入的机器
3、 读取客户端的请求信息
4、 返回数据

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务器类
 * @author Administrator
 *
 */
public class Server {

	public static void main(String[] args) {
		ServerSocket ss = null;
		BufferedWriter out = null;
		BufferedReader reader = null;
		try {
			//定义本机作为服务器,并针对本机上80这个端口进行数据侦听
			ss =  new ServerSocket(80);
			System.out.println("启动服务器成功,并侦听80端口!!!!!!!!");
			//这是一个阻塞式的方法
			Socket s = ss.accept();//侦听端口,并接受来自于该端口进入的机器的连接(这个类就好比"履带"对象)
			InetAddress addr = s.getInetAddress();//得到客户端IP地址对象
			System.out.println(addr.getHostAddress());//打印IP地址(客户端)
			System.out.println(addr.getHostName());//打印IP地址|域名|主机名(客户端)
			
			System.out.println("来了一个新的客户端!!!!!!!");
			//读取客户端的请求信息
			reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
			String info = reader.readLine();//一行一行的读取数据(阻塞式方法)
			System.out.println("来自于客户端信息:" + info);
			
			
			//返回数据
			String msg = "已接收到您的请求,请等待处理";
			out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			out.write(msg);
			out.newLine();
			out.flush();//刷新缓冲通道
			
		/*	while(true) {
				
			}*/
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

UDP
一、 类DatagramSocket DatagramPacket
客户端

  1. 创建客户端 DatagramSocket 类+端口(指定:数据从哪个端口出去)
  2. 准备数据,这些数据需要装配到字节数组中区
  3. 将数据打包DatagramPacket + 服务器地址及端口号 来完成打包
  4. 发送
  5. 释放资源
  6. package com.gezhi.udp;
package com.gezhi.udp;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class MyClient02 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/**
		 * 建立一个客户端+端口
		 */
		DatagramSocket client=null;
		byte[] data=null;
		DatagramPacket packet=null;
		try {
			client=new DatagramSocket(6666);
			double num=98.56;
			data=convert2Byte(num);
			packet=new DatagramPacket(data, data.length, new InetSocketAddress("127.0.0.1",8888));
			client.send(packet);
    	
			
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	/**
	 * 其他数据类型转换为byte数组
	 * @param num
	 * @return
	 * @throws Exception 
	 */
	private static byte[] convert2Byte(double num) throws Exception {
		// TODO Auto-generated method stub
		byte[] data=null;
		ByteArrayOutputStream bos=new ByteArrayOutputStream();
		DataOutputStream dos=new DataOutputStream(bos);
			dos.writeDouble(num);
			dos.flush();
			data=bos.toByteArray();
			bos.close();
			return data;
		
		
		
	}

}

服务端
1.创建服务端 DatagramSocket类+端口(指定:从哪个端口获取数据)
2.准备接收数据 需定义一个字节数组 封装DataGramPacket
3.接收数据
4.分析数据
5.释放资源

package com.gezhi.udp;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * 服务器端
 * @author Administrator
 *
 */
public class MyServer {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建服务器
		DatagramSocket sever=null;
		try {
			sever=new DatagramSocket(8888);
			//准备接收数据
			byte[] container=new byte[1024];
			DatagramPacket packet=new DatagramPacket(container, container.length);
			//接收数据
			sever.receive(packet);//阻塞方法
			//分析数据
			byte[] data=packet.getData();
			double nums=covert2Double(data);
    		System.out.println(nums);	
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		
	}
	
	

	/**
	 * 完成数组到double转换
	 * @param data
	 * @return
	 * @throws IOException 
	 */
	private static double covert2Double(byte[] data) throws IOException {
		// TODO Auto-generated method stub
		double num=0;
		ByteArrayInputStream bis=new ByteArrayInputStream(data);
		DataInputStream dis=new DataInputStream(bis);
			num=dis.readDouble();
		return num;
	}

}

URL类
URL(Uniform Resource Locator)代表统一资源定位,代表万维网上的一个资源,例如一个网页或者一个FTP目录。
一个URL实际上是一类URI(Uniform Resource Identifier,统一资源标识符)。URI标识一个资源,但是不包括如何访问该资源的信息。URL标识一个资源以及访问该资源的协议。URI在java中使用java.net.URI类代表。

public static void main(String[] args) {
		// TODO Auto-generated method stub

		URL url;
		try {
			url = new URL("https://www.baidu.com:80/s?ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=java.net.SocketException%3A%20Connection%20reset&rsv_pq=c36f3f840000cf0f&rsv_t=c9f73t9XrpUbpS9A8Qp1mFQ2BEgm2MHPIvB4KT4XvrpUmt%2B9jUE5FUp25KY&rqlang=cn&rsv_enter=1&rsv_n=2&rsv_sug3=1#nextpage.index");
			System.out.println("协议:"+url.getProtocol());//获得协议如http,https
			
			System.out.println("主机:"+url.getHost());//获得主机名
			
			 System.out.println("端口"+url.getPort());//获得端口号
			 
			 System.out.println("统一资源修饰符"+url.getFile());//获得url www.baidu.com
			 
			 System.out.println("查询参数"+url.getQuery());//?后的内容
			 
			 System.out.println("得到锚点:"+url.getRef());//#后的内容
			 
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值