服务器和客户端信息互相传送

网络编程

一.Socket和ServerSocket类
1.用来实现双向安全连接网络
2.ServerSocket创建一个服务器Scoket,定义一个端口号,然后用Socket定义一个客户端并定义其链接的IP地址和端口号
3.服务器和客户端内容相互传输服务端实现代码:

package com.qfedu.test1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 	服务端
 * @author WHD
 *
 */
public class Server {
	public static void main(String[] args) {
		// 通过ServerSocket 创建一个服务器Socket
		// 端口号 表示每一个应用程序唯一的编号  
		// 一些应用程序有默认的端口号 比如 tomcat 8080 mysql 3306 
		// 端口号取值范围 0~ 65535  我们在定义端口号的时候  9000以上都可以使用 
		
		try {
			ServerSocket ss  = new ServerSocket(8899);
			System.out.println("服务器启动完毕,等待连接。。。。。");
			Socket socket = ss.accept(); // 此时调用accept方法 程序将会阻塞 等待客户端连接
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String info = br.readLine();
			System.out.println("客户端发送的信息是:" + info);
			//传输客户端代码实现
			OutputStream os = socket.getOutputStream();
			os.write("睡了".getBytes());
			socket.shutdownOutput();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

package com.qfedu.test1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 	客户端
 * 	TCP Transmission Control Protocol
 * 	面向连接的 可靠 安全的 传输协议 
 * 	TCP连接和断开涉及到 三次握手 四次挥手
 * 	软件的分类
 * 	B/S Browser Server 基于浏览器的软件  代码编写相对简单 因为我们只需要编写一套代码 发布与服务器就可以
 * 	C/S Client Server  基于客户端的软件 代码相对复杂 因为我们要两套程序  一个客户端 一个服务器  维护难度
 * @author WHD
 *
 */
public class Client {
	public static void main(String[] args) {
		try {
			// 地址就写当前电脑的ip地址  
			// 本机的ip地址  localhost  等价  127.0.0.1 
			Socket socket = new Socket("localhost", 8899);
			System.out.println("客户端准备就绪。。。。。。");
			OutputStream os = socket.getOutputStream();
			os.write("服务器你好,睡了吗?".getBytes());
			socket.shutdownOutput(); // 关闭写入 输出流 
			
			//接收服务器内容传入
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			System.out.println("好激动,服务器回话了" + br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

服务器代码解释:
先用ServerSocket创建一个服务器端口号对象ss,然后用ss调用accept,程序阻塞,等待客户端信息传入,用ss.accept定义的socket调用getInputStream接受客户端写入的信息,并创建对象is然后用BufferedReader进行字节流缓冲,且需要传入new InputStreamReader(is),此代码含义为将getInputStream定义的is对象当参数传入InputStreamReader中,然后再将其创建的对象当作参数传入BufferedReader中,创建一个字符缓冲流对象,然后用此对象调用readLine()方法,将接受到的消息读取后传入info中转化为字符串进行输出。
用accept定义的socket调用getOutputStream()方法将客户端的话进行传输,用其创建的对象,调用write进行传入信息的进行传入,其中传入的信息需要调用getBytes()进行转化,然后用shutdownOutput()方法进行写入结束的声明。
客户端代码:

package com.qfedu.test1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 	客户端
 * 	TCP Transmission Control Protocol
 * 	面向连接的 可靠 安全的 传输协议 
 * 	TCP连接和断开涉及到 三次握手 四次挥手
 * 	软件的分类
 * 	B/S Browser Server 基于浏览器的软件  代码编写相对简单 因为我们只需要编写一套代码 发布与服务器就可以
 * 	C/S Client Server  基于客户端的软件 代码相对复杂 因为我们要两套程序  一个客户端 一个服务器  维护难度
 * @author WHD
 *
 */
public class Client {
	public static void main(String[] args) {
		try {
			// 地址就写当前电脑的ip地址  
			// 本机的ip地址  localhost  等价  127.0.0.1 
			Socket socket = new Socket("localhost", 8899);
			System.out.println("客户端准备就绪。。。。。。");
			OutputStream os = socket.getOutputStream();
			os.write("服务器你好,睡了吗?".getBytes());
			socket.shutdownOutput(); // 关闭写入 输出流 
			
			
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			System.out.println("好激动,服务器回话了" + br.readLine());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

代码解释:
用Socket进行和服务器进行连接,然后用getOutputStream进行数据的传输,其定义的对象进行信息的输入,shutdownOutput进行写入结束生命
getInputStream对服务器端传入数据进行读取,BufferedReader方法进行缓冲,具体解释看服务器,然后再输出语句中用缓冲对象调用readLine进行信息输出。
4.客户端对服务器进行对象的传输,定义的对象类记得序列化,不然不能进行字节流的传输,服务器具体代码实现:

package com.qfedu.test2;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

ublic class Server {
	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8899);
			System.out.println("服务器启动完毕……");
			Socket socket = ss.accept();
			InputStream is = socket.getInputStream();//接收返回的数据
			ObjectInputStream ois = new ObjectInputStream(is);
			Student stu = (Student) ois.readObject();
			System.out.println(stu);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

代码解释:
还是先用ServerSocket定义端口号,然后accept进行阻断,getInputStream接受客户端传入的数据,然后用ObjectInputStream进行信息转化,用气定义的对象调用readObject方法进行数据的读取并转化为我们将要输出的对象类,然后用输出语句直接输出。
客户端代码:

package com.qfedu.test2;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 	客户端
 * 	向服务器发送一个对象
 * @author WHD
 *
 */
public class Client {
	public static void main(String[] args) {
		try {
			Socket socket = new Socket("localhost", 8899);
			System.out.println("客户端开始发送数据……");
			OutputStream os = socket.getOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(os);
			oos.writeObject(new Student("赵四", 20));
			socket.shutdownOutput();
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
}

代码解释:
先用Socket连接服务器,getOutputStream对服务器进行信息输出,ObjectOutputStream将即将传入的信息进行转化,并存入getOutputStream定义的类中writeObject进行信息的写入,在writeObject中直接定义对象,shutdownOutput生命结束写入。
5.多个客户端一个服务器利用线程进行信息的相互传入服务器端代码如下:

package com.qfedu.test3;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 	服务器
 * 	因为目前是三个客户端来访问 所以我们要
 * 	1.服务器必须一值处于开启状态
 * 	2.可以使用多个线程来分别回应客户端
 * @author WHD
 *
 */
public class Server {
	public static void main(String[] args) {
		try {
			ServerSocket ss = new ServerSocket(8899);
			System.out.println("服务器启动……");
			while(true) {
				Socket socket  = ss.accept(); // 不同的客户端请求访问 返回的是不同的socket 
				// 执行完以上代码 程序继续 服务器将停止 所以我们编写一个线程类 代替服务器应答
			
				new ServerThread(socket).start();;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

代码解释:
ServerSocket创建端口号,然后accept进行阻塞,new ServerThread(socket).start();定义线程类调用线程,socket值不同代表不同的调用线程,其中while循环保证服务器一直处于激活状态
线程代码具体如下:

package com.qfedu.test3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 	当前了你作为服务器应答的线程类
 * 	如何区分不同的请求?
 * 	通过Socket 本类中声明一个属性 Socket
 * 	这个Socket将作为run方法中回应客户端的重要依据
 * @author WHD
 *
 */
public class ServerThread extends Thread{
	private Socket socket;

	public Socket getSocket() {
		return socket;
	}
	public void setSocket(Socket socket) {
		this.socket = socket;
	}
	public ServerThread(Socket socket) {
		this.socket = socket;
	}
	
	@Override
		public void run() {
			try {
				InputStream is = this.socket.getInputStream();
				BufferedReader br = new BufferedReader(new InputStreamReader(is));
				String line = null;
				while(( line =br.readLine()) != null) {
					System.out.println("客户端说的话: " + line);
				}
				
				OutputStream os = socket.getOutputStream();
				os.write("客户端你好,睡了".getBytes());
				socket.shutdownOutput();
				
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	
	
	
}

代码解释如下:
先创建一个socket类,接收服务器传入的不同线程类信息,this.socket.getInputStream();接收不同线程传入的不同信息,BufferedReader进行缓冲,并转化,定义一个line,用br.readLine()进行信息的遍历,并传入到line中,进行输出
信息输出时getOutputStream对客服端进行信息输出,os.write进行信息写入,getBytes()进行信息转化,socket.shutdownOutput()进行信息停止写入标识。
客户端代码如下:

package com.qfedu.test3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 	模拟多个客户端访问服务器 服务器 一一回应 
 * @author WHD
 *
 */
public class Client3 {
	public static void main(String[] args) {
		try {
			Socket socket = new Socket("localhost", 8899);
			OutputStream os = socket.getOutputStream();
			os.write("服务器你好,我是3号客户端".getBytes());
			socket.shutdownOutput();
			
			InputStream is = socket.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(is));
			String line = null;
			while(( line =br.readLine()) != null) {
				System.out.println("服务器回话了:" + line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			// 关闭资源
		}
	}
}

代码解释:
Socket连接客户端,getOutputStream()进行信息传入客户端,write信息写入,getBytes信息转化,shutdownOutput信息停止写入
getInputStream服务器传回信息读取,BufferedReader缓冲读取,定义字符串类line,br.readLine()信息的遍历,并传入line进行输出
二.DatagramSocket和DatagramPacket类:
服务器端代码:

package com.qfedu.test5;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;

/**
 * 	服务器
 * @author WHD
 *
 */
public class Server {
	public static void main(String[] args) {
		try {
			DatagramSocket ds =  new DatagramSocket(8899);
			System.out.println("服务器启动……");
			byte [] bag = new byte[1024];
			// 1 接收内容用的byte数组  --- 准备装快递包裹
			// 2 数组的长度    --- 包裹大小
			DatagramPacket dp = new DatagramPacket(bag, bag.length);
			ds.receive(dp); // 接收包裹
			// 拆快递的过程  
			System.out.println(new String(dp.getData(),0,dp.getData().length));
			
			
			String returnInfo  = "客户端hello";
			byte [] returnBag = returnInfo.getBytes();
			SocketAddress socketAddress = dp.getSocketAddress();
			// 第三个参数是SocketAddress 相当于回话给对方的地址 可以直接从已经接受过的包裹直接获取
			DatagramPacket dp1 = new DatagramPacket(returnBag, returnBag.length, socketAddress);
			ds.send(dp1);
			
			
			
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

DatagramSocket创建端口号,定义一个接收数组bag,并定义其长度,DatagramPacket用数组接收服务器传入的数据,用ds.receive(dp)进行读取遍历,System.out.println(new String(dp.getData(),0,dp.getData().length));输出数组,括号内的参数为接收自那个数组,偏移量,数组长度
将要传给客户端的信息封存到String修饰的对象中,用数组进行接收,获取客户端的端口信息,DatagramPacket对数组进行转化,ds.send(dp1);发送给客户端。
客户端代码:
package com.qfedu.test5;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/**
 * 	UDP 用户数据报协议 报文  数据包  
 * 	非面向连接 不安全 不可靠 效率高
 * @author WHD
 *
 */
public class Client {
	public static void main(String[] args) {
		String info = "hello 服务器";
		System.out.println("客户端准备发送信息……");
		byte [] datas = info.getBytes();
		InetAddress localHost;
		try {
			localHost = InetAddress.getLocalHost();
			// 1 发送的内容 ---包裹内容
			// 2 内容大小   --- 包裹的重量
			// 3 地址   --- 地址
			// 4 端口号 --- 联系方式
			DatagramPacket dp = new DatagramPacket(datas, datas.length, localHost, 8899);
			// 创建DatagramSocket 对象用于发送数据
			DatagramSocket ds = new DatagramSocket();
			ds.send(dp); // 通过send方法将打包好的内容发送
			
			
			byte [] saveBag = new byte[1024];
			DatagramPacket dp1 = new DatagramPacket(saveBag, saveBag.length);
			ds.receive(dp1);// 接收到包裹
			//拆快递
			System.out.println("服务器回话了:" + new String(dp1.getData(),0,dp1.getData().length));
			
			
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

代码解释:
将要传给服务器的信息存进String修饰的对象info中,将其转化为字符串存入数组中,定义端口号,getLocalHost获取本机端口号,并传给我们定义的端口号DatagramPacket读取数组信息,并连接服务器,DatagramSocket将DatagramPacket读取的信息进行转化,ds.send(dp);发送给客户端
定义一个数组和长度用于接收服务器传入的信息,DatagramPacket接收服务器传入的信息,并存进数组,ds.receive(dp1);对读取到的信息进行遍历,输出读取的那个数组,偏移量,和数组长度。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OPC(开放式连续控制协议)是一种通讯协议,用于连接工业控制系统(ICS)和计算机系统,以实现实时监测和控制的需求。 在 Python 中,你可以使用第三方库 `freeopcua` 来实现 OPC 服务器客户端互相发送信息。以下是一个简单的实例: ``` # 服务器端代码 import time import sys import FreeCAD from opcua import Server server = Server() url = "opc.tcp://localhost:4840" server.set_endpoint(url) name = "OPCUA_Server_Test" addspace = server.register_namespace(name) node = server.get_objects_node() Param = node.add_object(addspace, "Parameters") temp = Param.add_variable(addspace, "Temperature", 0) temp.set_writable() server.start() print("Server started at {}".format(url)) while True: time.sleep(1) # 客户端代码 import sys import time import FreeCAD from opcua import Client client = Client("opc.tcp://localhost:4840/") client.connect() print("Client connected to OPC UA Server") while True: try: temp = client.get_node("ns=1;i=1002") temperature = temp.get_value() print("Temperature: ", temperature) time.sleep(1) except KeyboardInterrupt: client.disconnect() sys.exit(0) ``` 上面的代码实现了一个服务器端,监听来自客户端的请求,并且客户端连接到服务器端并不断读取数据。你可以修改代码以实现自己的需求。 ### 回答2: Python OPC服务器客户端可以通过互相发送信息来实现数据交换。OPC(OLE for Process Control,工业自动化控制系统的标准)是一种通信协议,用于在工业控制系统中传输数据。 下面是使用Python编写的简单示例,演示了如何在Python OPC服务器客户端之间互相发送信息。 首先,我们需要安装所需的Python库。使用pip命令安装`opcua`库。 ``` pip install opcua ``` 然后,我们创建一个Python OPC服务器服务器将在本地主机的地址`opc.tcp://localhost:4840`上运行,监听来自客户端的连接。 ```python from opcua import ua, Server server = Server() server.set_endpoint("opc.tcp://localhost:4840") # 创建命名空间 uri = "my_namespace_uri" idx = server.register_namespace(uri) # 添加对象到根节点 objects = server.get_objects_node() myObject = objects.add_object(idx, "MyObject") # 添加变量到对象 myVar = myObject.add_variable(idx, "MyVariable", 0) myVar.set_writable() # 启动服务器 server.start() print("OPC服务器已启动") # 持续更新变量值 count = 0 while True: myVar.set_value(count) count += 1 ``` 上述代码创建了一个名为`MyVariable`的变量,并不断更新其值。 接下来,我们创建一个Python OPC客户端,以连接到上述服务器并获取变量的值。 ```python from opcua import ua, Client # 创建客户端 client = Client("opc.tcp://localhost:4840") client.connect() # 获取根节点 root = client.get_root_node() # 获取对象和变量 myObject = root.get_child(["0:Objects", "2:MyObject"]) myVar = myObject.get_child(["2:MyVariable"]) # 获取并打印变量的值 value = myVar.get_value() print("变量值:", value) # 断开客户端连接 client.disconnect() ``` 上述代码创建了一个客户端,并连接到本地主机的`opc.tcp://localhost:4840`地址上的OPC服务器。然后,它获取了服务器上的变量并打印其值。 这是一个简单的示例,演示了如何在Python OPC服务器客户端之间互相发送信息。根据实际需求,可以进一步扩展和定制服务器客户端的功能。 ### 回答3: Python OPC(OLE for Process Control)服务器客户端是用于在工业自动化系统中进行数据交互的重要工具。服务器是用来提供数据的地方,而客户端则用来请求并接收这些数据。 下面是一个简单的Python OPC服务器客户端互相发送信息的实例: ```python # OPC服务器端示例 from opcua import Server # 创建服务器对象 server = Server() # 添加一个命名空间 uri = "opc.tcp://localhost:4840" server.set_endpoint(uri) name = "OPCServer" addspace = server.register_namespace(name) # 创建节点对象并添加根节点 root_node = server.get_objects_node() object_node = server.get_objects_node().add_object(addspace, "Object") # 添加变量节点 var_node = object_node.add_variable(addspace, "Variable", 0) # 启动服务器 server.start() # 循环更新变量值 count = 0 while True: count += 1 var_node.set_value(count) time.sleep(1) # 关闭服务器 server.stop() ``` ```python # OPC客户端示例 from opcua import Client # 创建客户端对象 client = Client("opc.tcp://localhost:4840") # 连接到OPC服务器 client.connect() # 获取服务器对象 objects = client.get_objects_node() # 获取变量节点对象 var_node = objects.get_child(["0:opcserver", "0:Object", "0:Variable"]) # 循环读取变量值 while True: value = var_node.get_value() print("Variable value:", value) time.sleep(1) # 断开连接 client.disconnect() ``` 以上示例中,OPC服务器通过创建变量节点,并在循环中更新该节点的值,客户端则通过连接到服务器,并在循环中读取该节点的值。通过这种方式,服务器客户端可以互相发送信息并交换数据。 在实际应用中,可以根据需要添加更多的节点和变量,以及相应的读写操作来满足特定的数据交互需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值