Java中网络编程重点总结

IP地址(Internet  Protocol):唯一标识网络上的每一台计算机

IP地址的组成:32位,由4个8位二进制数组成

二进制变成十进制方法:位数数值乘以2的位数次方,最大到255

 

IP地址 = 网络地址 +主机地址

网络地址:标识计算机或网络设备所在的网段

主机地址:标识特定主机或网络设备

IP地址的配置和检测:

查看IP地址,检测网络是否畅通

查看本机的IP地址:ipconfig

测试网络是否通畅:ping (再加上)目标IP地址

【1. 开始里面直接输入cmd;2. 打开dos系统;3. 输入代码】

DNS域名解析:Domain Name System,域名系统

为了好访问,好记忆。通过DNS

 

网络服务器:

通常指在网络环境下,具有较高计算能力,能够提供用户服务功能的计算机

B/S:浏览器服务器端的服务程序【好处:服务器端自己升级就行了】

C/S:客户端服务器端的服务程序

 

网络通信协议:

为在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合

【数据在网络中传输是很复杂的】

HTTP协议:超文本传输协议,互联网应用最广泛的。

FTP协议:文件传输协议。

SMTP协议:简单邮件传输协议。

TCP协议(Transmission Control Protocol 传输控制协议):面向连接的、可靠的、基于字节流的传输通信协议。

UDP协议(User Datagram Protocol 用户数据报协议):无连接的协议,在传输数据之前,客户端和服务器并不建立和维护连接,效率很快。

 

Socket:

通信链路的端点就被称为“套接字”(英文名Socket);是提供给应用程序的接口

【Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制】

Socket分类

  1. 流式套接字(SOCK_ STREAM)【面向连接、可靠的数据传输服务(对应服务是TCP链接)】
  2. 数据报式套接字(SOCK_ DGRAM)【无连接服务(数据报似的,基于UDP)更高效】
  3. 原始式套接字(SOCK_ RAW)

 

java.net包:

Socket

ServerSocket

DatagramPacket

DatagramSocket

InetAddress

……

基于TCP协议的Socket网络通信:用来实现双向安全连接网络通信

Socket通信模型:进行网络通信时,Socket需要借助数据流来完成数据的传递工作

                  C:客户端                                                           S:服务器

Socket网络编程一般可以分成如下步骤进行:

Servicer

Client

1. 创建ServerSocket(…)对象,绑定某一哥端口号

1. 创建Socket("…",…)要指定服务器的IP地址,也要指定端口号

2. 通过accept()侦听方法,阻塞,等待对方连接

 发送请求并被accept()侦听到,并建立           连接

3. 通过输入、输出流传递信息【客户端是输出输入,服务器是输入输出】

4. 关闭释放资源

例1【直接传参数的方法】:

服务器端程序:

public class LogicServicer {
	public static void main(String[] args) {
		try {
			//接收客户端请求
			//创建一个Socket
			ServerSocket serverSocket = new ServerSocket(5000);
			//使用accept()侦听并接收到此ServerSocket的连接
			Socket socket = serverSocket.accept();//侦听到之前都是阻塞的
			//获得输入流,获得用户的请求
			//数据流输入
			InputStream is = socket.getInputStream();
			// BufferedReader读取字符流
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String info;
			// BufferedReader的方法可以一行一行的读
			while((info = br.readLine())!=null){
				System.out.println("客户端:"+info);
			}
			//给客户端一个响应
			String reply = "欢迎登陆";
			//通过输出流将响应发送回给客户端
			OutputStream os = socket.getOutputStream();
			os.write(reply.getBytes());	
			//释放相应资源
			os.close();
			br.close();
			is.close();
			socket.close();
			serverSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		} } }

客户端程序:

public class LogicClient {
	public static void main(String[] args) {
		//创建一个客户端的Socket
		try {
			Socket socket = new Socket("localhost",5000);
			//通过输出流发送请求
			//直接输出数据流
			String info = "用户名:樱桃小丸子;密码:123456";
			OutputStream os = socket.getOutputStream();
			//打散成数据数组
			byte[] infos = info.getBytes();
			os.write(infos);
			//关闭输出流,这是一个半关闭
			socket.shutdownOutput();
			//通过输入流接收服务器给我的响应
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while((reply = br.readLine())!=null){
				System.out.println("服务器:"+reply);
			}
			//释放资源
			os.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} } }

测试结果:

例2【通过用户对象传参数的方法】:

用户类程序:

public class User implements Serializable{
	private String userName;
	private String pwd;
	public User() {}
	public User(String userName, String pwd) {
		this.userName = userName;
		this.pwd = pwd;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	} }

服务器端程序:

public class LogicServicer {
		public static void main(String[] args) {
			try {
				//接收客户端请求
				//创建一个Socket
				ServerSocket serverSocket = new ServerSocket(5000);
				//使用accept()侦听并接收到此ServerSocket的连接
				Socket socket = serverSocket.accept();//侦听到之前都是阻塞的
				//获得输入流,获得用户的请求
				//将对象反序列化变成输入流
				InputStream is = socket.getInputStream();
				ObjectInputStream ois = new ObjectInputStream(is);
				User user = (User)ois.readObject();
				System.out.println("客户端:"+user.getUserName()+"-"+user.getPwd());
				//给客户端一个响应
				String reply = "欢迎登陆";
				//通过输出流将响应发送回给客户端
				OutputStream os = socket.getOutputStream();
				os.write(reply.getBytes());	
				//释放相应资源
				ois.close();
				os.close();
				is.close();
				socket.close();
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} } } 

客户端类:

public class LogicClient {
	public static void main(String[] args) {
		//创建一个客户端的Socket
		try {
			Socket socket = new Socket("localhost",5000);
			//通过输出流发送请求
			//将对象序列化变成输出流
			User user = new User("樱桃小丸子","123456");
			OutputStream os = socket.getOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(os);
			oos.writeObject(user);
			//关闭输出流,这是一个半关闭
			socket.shutdownOutput();
			//通过输入流接收服务器给我的响应
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while((reply = br.readLine())!=null){
				System.out.println("服务器:"+reply);
			}
			//释放资源
			os.close();
			oos.close();
			socket.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} } }

测试结果:

如何实现多客户请求呢?

  1. 采用多线程的方式
  2. 一个专门负责监听的应用主服务程序
  3. 一个专门负责处理请求的线程程序

例题:

实现服务器和客户端的多线程连接;并且服务器和客户端可以无限对话。

实现思路:

服务器:

一直监听客户请求

一旦监听到有客户请求,立即创建一个线程,开启线程

线程:

接收客户请求,基于客户一个响应(这是之前服务器要做的事)

线程构造方法中去绑定客户端的Socket

客户端:

发送请求到服务器

接收服务器的响应

例如:

线程类:

//接收客户请求,基于客户一个响应(这是之前服务器要做的事)
//线程构造方法中去绑定客户端的Socket
public class LogicThread extends Thread {
	private Socket socket;
	public LogicThread(Socket socket){
		this.socket=socket;
	}
	//接收客户请求,基于客户一个响应
	public void run(){
		InputStream is=null;
		BufferedReader br=null;
		PrintWriter pw=null;
		OutputStream os=null;
		try{
			Scanner input = new Scanner(System.in);
			//获得输入流,获得用户的请求
			while(true){
				is= socket.getInputStream();
				br = new BufferedReader(new InputStreamReader(is));
				System.out.println(socket.getInetAddress()+"说"+br.readLine());
				//给客户端一个响应
				//通过输出流将响应发送回给客户端
				String reply =input.next();
				os = socket.getOutputStream();
				pw = new PrintWriter(os);
				pw.println(reply);
				pw.flush();
			}
			//释放相应资源
		}catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				pw.close();
				os.close();
				br.close();
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			} } } }

服务器程序:

//一直监听客户请求
//一旦监听到有客户请求,立即创建一个线程,开启线程
public class LogicServicer {
	public static void main(String[] args) {
		try {
			//接收客户端请求
			//创建一个Socket
			ServerSocket serverSocket = new ServerSocket(8848);
			System.out.println("启动服务器");
			//使用accept()侦听并接收到此ServerSocket的连接
			//一直监听客户请求
			while(true){
				Socket socket = serverSocket.accept();//侦听到之前都是阻塞的
				System.out.println("已连接");
				//创建一个和该客户端响应的线程
				LogicThread logicThread = new LogicThread(socket);
				logicThread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} } }

客户端类:

//发送请求到服务器
//接收服务器的响应
public class LogicClient {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		OutputStream os=null;
		PrintWriter pw=null;
		InputStream is=null;
		BufferedReader br=null;
		//创建一个客户端的Socket
		try {
			Socket socket = new Socket("localhost",8848);
			System.out.println("客户端已启动");
			//通过输出流发送请求
			while(true){
			String info =input.next();
			os = socket.getOutputStream();
			pw = new PrintWriter(os);
			pw.println(info);
			pw.flush();
			//通过输入流接收服务器给我的响应
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			System.out.println("服务器:"+br.readLine());
			}
			//释放资源
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				try {
					os.close();
					pw.close();
					br.close();
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} } } }

测试结果:

如何获得客户的IP?

InetAddress(IP地址的封装)

应用实例:

InetAddress ia = socket.getInetAddress();

String ip= ia.getHostAddress();

 

基于UDP协议的Socket编程:

 

TCP

UDP

是否连接

面向连接

面向非连接

传输可靠性

可靠

不可靠

速度

 

基于UDP协议的Socket网络编程步骤

  1. 利用 DatagramPacket 对象封装数据报
  2. 利用 DatagramSocket 发送数据报
  3. 利用 DatagramSocket 接收数据报
  4. 利用 DatagramPacket 处理数据报

DatagramPacket类

封装了数据报的数据、数据长度、目标地址和目标端口

DatagramSocket类

接收和发送DatagramPacket对象封装好的数据报

【两个类都在java.net包里】

例子:

礼物—数据(字符串)

包裹—DatagramPacket

快递点—DatagramSocket

寄礼物—send()

收礼物—receive()

基于UDP的Socket通信,服务端:

public class LogicServicer {
	public static void main(String[] args) {	
		byte[] infos = new byte[1024];
		DatagramPacket dp = new DatagramPacket(infos,infos.length);
		//快递点
		DatagramSocket socket=null;
		try {
			socket = new DatagramSocket(5000);
			//在快递点取礼物
			socket.receive(dp);
			//拆礼物
			String info = new String(dp.getData(),0,dp.getData().length);
			System.out.println("客户端说:"+info);	
			//给客户端一个响应
			String reply ="一件羽绒服";
			byte[] reply2 = reply.getBytes();
			//客户端地址
			SocketAddress sa = dp.getSocketAddress();
			//打开一个包裹
			DatagramPacket dp1 = new DatagramPacket(reply2,reply2.length,sa);
			//寄出去
			socket.send(dp1);	
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			socket.close();
		} } }

基于UDP的Socket通信,客户端:

public class LogicClient {
	public static void main(String[] args) {
		//买礼物
		String info="心形巧克力!";
		byte[] infos = info.getBytes();
		//对方地址和邮编(端口号)
		InetAddress ia;
		//快递点
		DatagramSocket socket = null; 
		try {
			ia = InetAddress.getByName("localhost");
			//包裹包装礼物
			DatagramPacket dp = new DatagramPacket(infos, infos.length, ia, 5000);
			socket = new DatagramSocket();
			//通过快递点往外寄出礼物
			try {
				socket.send(dp);
			} catch (IOException e) {
				e.printStackTrace();
			}
			//接收服务器的响应
			byte[] replys = new byte[1024];
			DatagramPacket dp1 = new DatagramPacket(replys,replys.length);
			socket.receive(dp1);
			String reply = new String(dp1.getData(),0,dp.getData().length);
			System.out.println("服务器的响应:"+reply);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			socket.close();
		} } }

测试结果:

  • 11
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
在PB使用WINSOCK.OCX做双向通信的简单例子----PowerBuilder 一、在窗口添加WINSOCK控件:   在应用新开一个窗口,在窗口画板点击controls-->OLE菜单项,弹出 Insert object窗口,单击Insert control标签,从列表框双击选定 Microsoft Winsock control,将winsock的图标贴在窗口上。   在程序该控件名称定为winsock_a(甲方)和winsock_b(乙方)。   二、设置信息输入输出文本框:   在窗口增加一个按钮cb_1,两个单行文本框sle_1,sle_2,分别用于输入 要发送的字符串和接受对方发送的字符串。   三、设置通讯协议:   WINSOCK控件允许用户以UDP和TCP两种协议任选一种进行通讯。   1.UDP协议设置:UDP协议是一种无连接的通讯协议,在通讯之前,需要绑 定remotehost和remoteport属性,如果需要双向通讯,还要设置localport属性 。   在甲方(本机地址为:134.1.1.1)窗口的Open事件加入如下语句: winsock_a.object.protocol=1 //winsock通讯协议设为UDP协议 winsock_a.object.remotehost="134.1.1.2" //对方的ip地址 winsock_a.object.remoteport=6000 //对方的winsock通讯端口号 winsock_a.object.localport=6001 //本机的winsock通讯端口号 winsock_a.object.bind //绑定通讯协议   在乙方(本机地址为:134.1.1.2)窗口的Open事件加入如下语句: winsock_b.object.protocol=1 //winsock通讯协议设为UDP协议 winsock_b.object.remotehost="134.1.1.1" //对方的ip地址 winsock_b.object.remoteport=6001 //对方的winsock通讯端口号 winsock_b.object.localport=6000 //本机的winsock通讯端口号 winsock_b.object.bin //绑定通讯协议   2.TCP协议设置:TCP协议在通讯前需要进行连接。   在甲方(作为服务器端)窗口的Open事件加入如下语句: winsock_a.object.protocol=0 //winsock通讯协议设为TCP协议 winsock_a.object.localport=6001 //本机的winsock通讯端口号 winsock_a.listen() //启动监听   在甲方winsock_a控件的Connectionrequest事件加入如下语句: //接受到对方的连接请求后 if winsock_a.object.state0 then winsock_a.close() end if winsock_a.accept(requestID) //建立直接连接 //requestID是Connectionrequest事件自己的参数   在乙方(作为客户端)窗口的Open事件加入如下语句: winsock_b.object.protocol=0 //winsock通讯协议设为TCP协议 winsock_b.object.remotehost="134.1.1.2" //对方的ip地址 winsock_b.object.remoteport=6000 //对方的winsock通讯端口号 winsock_b.connect() //发出连接请求   3.无论采用哪种协议,都要在窗口的Close事件加入如下语句: if winsock_a/*或winsock_b*/.object.state0 then winsock_a.close() end if   否则可能第二次使用时发生异常问题   四、开始通讯   在按钮cb_1(caption属性设为‘发送’)的click事件加入如下语句: winsock_a/*或winsock_b*/.object.send (sle_1.text)   在winsock_a/*或winsock_b*/控件的dataarrival事件加入如下语句: //接受到对方数据后 string datastr1 winsock_a/*或winsock_b*/.object.getdata (def datastr1) sle_2.text=datastr1 //将数据字符串显示在文本框   以上程序实际上体现了聊天器的底层工作原理,稍加修改扩充就可以做成
在开发五子棋的小程序时,主要涉及以下几个Java知识点: 1. 面向对象的思想:通过创建一个名为Chess的类,将棋子对象化,使用该类的对象来表示棋子的行、列和标识。这样可以更方便地进行悔棋操作和棋盘的重绘。 2. 使用数组和二维数组:通过使用数组和二维数组来表示棋盘和棋子的状态。可以根据棋子对象所在的行、列信息,在二维数组设置对应位置的值来表示棋子的存在。同时,可以根据数组的值来判断游戏的胜负。 3. 事件监听器(Listener):使用GoListener类来监听玩家的操作,如鼠标点击棋盘的位置来下棋。该类的相关方法负责处理玩家的操作,并更新棋盘和棋子的状态。例如,实现悔棋功能时,根据棋盘上的棋子顺序数组,删除最后一颗棋子,并在棋盘和棋子数组相应位置进行更新。 4. 图形界面的绘制:通过使用Java的图形库,可以实现五子棋的可视化界面。绘制棋盘和棋子的图形,并随着玩家的操作进行更新。 5. 网络编程:在开发五子棋游戏大厅时,可能还涉及到Socket编程的相关知识点。这可以用来实现游戏大厅的功能,如动态加载游戏,让玩家选择进入游戏等。 总结来说,五子棋的Java知识点重点包括面向对象的思想、数组和二维数组的使用、事件监听器、图形界面的绘制以及可能的网络编程。这些知识点是开发五子棋小程序的关键所在。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值