java学习-网络编程

一、前期配置:安装tomcat服务器

现代的应用程序都离不开网络,网络编程是非常重要的技术。Java SE提供java.net包,其中包含了网络 编程所需要的最基础一些类和接口。这些类和接口面向两个不同的层次:基于Socket的低层次网络编程和基于URL的高层次网络编程。

所谓高低层次就是通信协议的高低层次,Socket采用TCP、UDP等协议,这些协议属于低层次的通信协议;URL采用HTTP和HTTPS这些属于高层次的通信协议。

低层次网络编程,因为它面向底层,比较复杂,但是“低层次网络编程”并不等于它功能不强大。恰恰相反,正因为层次低,Socket编程与基于URL的高层次网络编程比较,能够提供更强大的功能和更灵活的控 制,但是要更复杂一些。

1、环境配置:

下载Tomcat安装包,解压之后,进入bin目录,复制其路径

 进入高级系统设置,配置环境变量

 进入path编辑,新建一个环境变量,复制bin地址,之后蒂点击确定

 2、运行

进入bin目录,双击startup.bat运行,如果闪退,原因可能是因为在配置java环境中,配置有误,或者没有配置成HOME的模式。

 运行之后,发现中文部分乱码,这因为,tomcat在配置时候,输入到控制台的编码格式是UTF-8,如果需要改,就进入conf目录,选择logging.properties日志文件,更改java.util.logging.ConsoleHandler.encoding的值为GBK

 注意:运行startup.bat的窗口不要关闭,一旦关闭就认为服务器关闭,

测试服务器是否开启成功,在网浏览器输入http://localhost:8080/,服务器配置成功会进入Tomcat的欢迎页面,如下

 如果启动失败,大部分原因是端口已被占用,特别是网站开发者而言,很容易遇到这种问题,因为大部分的网站开发语言的默认端口就是8080端口,所以导致8080容易被占用。

进入conf目录,选择server.xml,右击选择打开方式,选择记事本打开 ,找到更改port的值,就是更该端口号,之后保存

3、简单测试:在浏览器中访问文件

进入webapps目录,新建test文件,里面存放你要访问的文件。webapps目录用来存放应用程序。当tomcat启动时会去加载webapps目录下的应用程序。可以以文件夹、war包、jar包的形式发布应用

 要重新运行startup.bat,这是因为,我们刚刚在里面写文件,还没刷新,此时访问的话,浏览器会查找不到该文件,所以要重新运行startup.bat。

之后再网页上输入http://localhost:8089/test/hello.txt

二、网络编程基础

1、网络模型:OSI与TCP/IP

2、ip地址

为实现网络中不同计算机之间的通信,每台计算机都必须有一个与众不同的标识,这就是IP地址, TCP/IP使用IP地址来标识源地址和目的地址。最初所有的IP地址都是32位数字构成,由4个8位的二进 制数组成,每8位之间用圆点隔开,如:192.168.1.1,这种类型的地址通过IPv4指定。而现在有一种新 的地址模式称为IPv6,IPv6使用128位数字表示一个地址,分为8个16位块。尽管IPv6比IPv4有很多优 势,但是由于习惯的问题,很多设备还是采用IPv4。不过Java语言同时指出IPv4和IPv6。

在IPv4地址模式中IP地址分为A、B、C、D和E等5类:

  • A类地址用于大型网络,地址范围:1.0.0.1~126.155.255.254。
  • B类地址用于中型网络,地址范围:128.0.0.1~191.255.255.254。
  • C类地址用于小规模网络,192.0.0.1~223.255.255.254。
  • D类地址用于多目的地信息的传输和作为备用。
  • E类地址保留仅作实验和开发用。

另外,有时还会用到一个特殊的IP地址127.0.0.1,127.0.0.1称为回送地址,指本机。主要用于网络软件 测试以及本地机进程间通信,使用回送地址发送数据,不进行任何网络传输,只在本机进程间通信

 3、端口

一个IP地址标识这一台计算机,每一台计算机又有很多网络通信程序在运行,提供网络服务或进行通 信,这就需要不同的端口进行通信。如果把IP地址比作电话号码,那么端口就是分机号码,进行网络 通信时不仅要指定IP地址,还要指定端口号。

TCP/IP系统中的端口号是一个16位的数字,它的范围是0~65535。小于1024的端口号保留给预定义的服 务,如HTTP是80,FTP是21,Telnet是23,Email是25等,除非要和那些服务进行通信,否则不应该使 用小于1024的端口

三、网络编程-基本操作

1、读取网络上的资源

访问网络上的资源,输出到控制台上:

import java.io.*;
import java.net.*;

public class One {

	public static void main(String[] args) throws Exception {
		URL url=new URL("http","localhost",8089,"/test/hello.txt");//实例化URl对象
		URLConnection uc=url.openConnection(); //得到网络连接对象
		InputStream is=uc.getInputStream();//得到网络资源的输入流
		InputStreamReader isr=new InputStreamReader(is);//转化为字符流
		BufferedReader br=new BufferedReader(isr);//转化为字符缓冲流读取
		String word=null;
		while((word=br.readLine())!=null) {
			System.out.println(word);
		}
		br.close();
		isr.close();
		is.close();
	}
}

2、网络资源的编码和解码

import java.io.*;
import java.net.*;
public class One {
	public static void main(String[] args) throws Exception {
		String word="hello,大家好";
		String newstr=URLEncoder.encode(word);
		System.out.println("编码后:"+newstr);
		String decode=URLDecoder.decode(newstr);
		System.out.println("解码后:"+decode);
		
	}
}

 四,网络编程-基于TCP协议的操作

1、Socket类与ServerSocket类

java.net包为TCP Socket编程提供了两个核心类:Socket和ServerSocket,分别用来表示双向连接的客户 端和服务器端

Socket常用的构造方法有:

  • Socket(InetAddress address, int port) :创建Socket对象,并指定远程主机IP地址和端口号。
  • Socket(InetAddress address, int port, InetAddress localAddr, int localPort):创建Socket对象,并指定 远程主机IP地址和端口号,以及本机的IP地址(localAddr)和端口号(localPort)
  • Socket(String host, int port):创建Socket对象,并指定远程主机名和端口号,IP地址为null,null 表示回送地址,即127.0.0.1。
  • Socket(String host, int port, InetAddress localAddr, int localPort):创建Socket对象,并指定远程主 机和端口号,以及本机的IP地址(localAddr)和端口号(localPort)。host主机名,IP地址为 null,null表示回送地址,即127.0.0.1。

Socket其他的常用方法有:

  • InputStream getInputStream():通过此Socket返回输入流对象。
  • OutputStream getOutputStream():通过此Socket返回输出流对象。 int getPort():返回Socket连接到的远程端口。
  • int getLocalPort():返回Socket绑定到的本地端口。 InetAddress getInetAddress():返回Socket连接的地址。
  • InetAddress getLocalAddress():返回Socket绑定的本地地址。 boolean isClosed():返回Socket是否处于关闭状态。
  • boolean isConnected():返回Socket是否处于连接状态。 void close():关闭Socket。

注意 Socket与流类似所占用的资源,不能通过JVM的垃圾收集器回收,需要程序员释放。一种方法是可以在finally代码块调用close()方法关闭Socket,释放流所占用的资源。另一种方法通过自 动资源管理技术释放资源,Socket和ServerSocket都实现了AutoCloseable接口。

ServerSocket类常用的构造方法有:

  • ServerSocket(int port, int maxQueue):创建绑定到特定端口的服务器Socket。maxQueue设置连接 的请求最大队列长度,如果队列满时,则拒绝该连接。默认值是50。
  • ServerSocket(int port):创建绑定到特定端口的服务器Socket。最大队列长度是50。

ServerSocket其他的常用方法有:

  • InputStream getInputStream():通过此Socket返回输入流对象。
  • OutputStream getOutputStream():通过此Socket返回输出流对象。
  • boolean isClosed():返回Socket是否处于关闭状态。
  • Socket accept():侦听并接收到Socket的连接。此方法在建立连接之前一直阻塞。
  • void close():关闭Socket。

ServerSocket类本身不能直接获得I/O流对象,而是通过accept()方法返回Socket对象,通过Socket对象取 得I/O流对象,进行网络通信。此外,ServerSocket也实现了AutoCloseable接口,通过自动资源管理技 术关闭ServerSocket。

2、客户端向服务端发送信息:

客户端类Client

import java.io.*;
import java.net.*;

public class Client {

	public static void main(String[] args) throws Exception {
		Socket socket=new Socket("localhost",9999);//实例化一个基于客户端的Socket对象,参数是目标主机和目标主机的端口号
		OutputStream os=socket.getOutputStream(); //输出流对象,用于发送信息
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
		bw.write("服务器,你好!!,我是客户端");
		bw.close();
		socket.close();
	}

}

服务器端Server类:

import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
		ServerSocket ssocket=new ServerSocket(9999);  //实例化一个基于服务器端的socket对象
		Socket socket =ssocket.accept();//监听9999号端口,有信息发送就立马获取客户端的socket对象
		InputStream is=socket.getInputStream();//获取内容,转化为输入流
		BufferedReader br=new BufferedReader(new InputStreamReader(is));
		System.out.println(br.readLine());
		br.close();
		is.close();
		socket.close();
		ssocket.close();
		
	}
}

 3、服务器端响应客户端

客户端类Client

public static void main(String[] args) throws Exception {
		//向服务器发送信息
		Socket socket=new Socket("localhost",9999);//实例化一个基于客户端的Socket对象,参数是目标主机和目标主机的端口号
		OutputStream os=socket.getOutputStream(); //输出流对象,用于发送信息
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
		bw.write("服务器,你好!!,我是客户端");
		bw.flush();//刷新
		//接收服务器信息
		socket.shutdownOutput(); //把socket关于写的操作先关闭掉
		InputStream is=socket.getInputStream();//获取信息,转化为输入流
		BufferedReader br=new BufferedReader(new InputStreamReader(is));
		System.out.println(br.readLine());
		//关闭
		os.close();
		bw.close();
		br.close();
		is.close();
	}

服务器端类Server:

import java.io.*;
import java.net.*;
public class Server {
	public static void main(String[] args) throws Exception {
		//接收客户端发送的信息
		ServerSocket ssocket = new ServerSocket(9999); //实例化一个基于服务器端的socket对象
		Socket socket = ssocket.accept(); //调用侦听的功能,侦听9999端口,侦听到了就直接获得该客户端的socket对象
		InputStream is = socket.getInputStream();//获取客户端内容,转化为输入流
		BufferedReader br = new BufferedReader(new InputStreamReader(is));//转换为缓冲字符输出流,进行输出
		System.out.println(br.readLine());
		//回应客户端
		OutputStream os = socket.getOutputStream(); //获取输出流
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));//转化为字符缓冲输出流,进行输出
		bw.write("客户端你好,信息我已收到!!");
		//关闭
		bw.flush();
		bw.close();
		os.close();
		br.close();
		is.close();
	}
}

4、客户端向服务器端传输对象信息

客户端向服务器端传输的都是数据流,所以要使得客户端能够传输对象信息到服务器端,要把对象序列化

user类:

import java.io.Serializable;

public class User implements Serializable{
	private static final long serialVersionUID = 1L;
	private String account;  //账户
	private String password; //密码
	public String toString() {
		return "User [account=" + account + ", password=" + password + "]";
	}
	public User(String account, String password) {
		super();
		this.account = account;
		this.password = password;
	}
	public User() {
		super();
	}
	public String getAccount() {
		return account;
	}
	public void setAccount(String account) {
		this.account = account;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

客户端Client:

import java.io.*;
import java.net.*;

public class Client {

	public static void main(String[] args) throws Exception {
		//向服务器发送对象信息
		Socket socket=new Socket("localhost",9999);//实例化一个基于客户端的Socket对象,参数是目标主机和目标主机的端口号
		OutputStream os=socket.getOutputStream(); //输出流对象,用于发送信息
		User user=new User("admin","123456");//实例化User对象
		ObjectOutputStream oos=new ObjectOutputStream(os);//序列化对象
		oos.writeObject(user);//将指定的对象写入ObjectOutputStream
		//关闭
		oos.close();
		os.close();
		socket.close();
	}

}

Server类:

import java.io.*;
import java.net.*;
public class Server {
	public static void main(String[] args) throws Exception {
		//接收客户端发送的对象信息
		ServerSocket ssocket = new ServerSocket(9999); //实例化一个基于服务器端的socket对象
		Socket socket = ssocket.accept(); //调用侦听的功能,侦听9999端口,侦听到了就直接获得该客户端的socket对象
		InputStream is = socket.getInputStream();//获取客户端内容,转化为输入流
		ObjectInputStream  ois=new ObjectInputStream(is);//反序列化对象
		Object obj=ois.readObject();//从ObjectInputStream读取一个对象
		User user = (User)obj; //转化为User类型
		if("admin".equals(user.getAccount())&&"123456".equals(user.getPassword())) { //进行账号密码匹配
			System.out.println("登录成功");
		}
		else {
			System.out.println("用户名或者密码不正确");
		}
		//关闭
		ois.close();
		is.close();
		socket.close();
		ssocket.close();
	}
}

5、客户端与服务器端自由交流

有两个方法实现,可以直接实现,也可以利用子线程实现

方法一:直接实现

客户端Client:

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Client {
	public static void main(String[] args) throws Exception {
		Scanner input = new Scanner(System.in);
		Socket socket = new Socket("192.168.23.18",9999); // 实例化一个基于客户端的Socket对象,目标主机和目标主机的端口号,目标主机这里采用本电脑的ip
		while(true) {
			//发送信息
			OutputStream os = socket.getOutputStream();//得到输出流对象,用于发送信息
			DataOutputStream dos = new DataOutputStream(os);//实例化数据输出流,将原始Java数据类型写入输出流,应用程序可以使用数据输入流来读取数据
			dos.writeUTF("客户端说:"+input.next());//发送信息给服务器端
			dos.flush();
			//接收响应数据
			InputStream is = socket.getInputStream();得到输入流对象,用于读取信息
			DataInputStream dis = new DataInputStream(is);//转化为数据输入流,便于直接读取
			System.out.println(dis.readUTF());
		}
	}
}

服务器端:

import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Server {
	public static void main(String[] args) throws Exception {
		//接收客户端发送的对象信息
		Scanner input = new Scanner(System.in);	
		ServerSocket ssocket = new ServerSocket(9999); //实例化一个基于服务器端的socket对象
		Socket socket = ssocket.accept(); //调用监听功能,侦听9999端口,有信息就直接获得该客户端的socket对象
		while(true) {
			//接收信息
			InputStream is = socket.getInputStream();
			DataInputStream dis = new DataInputStream(is);
			System.out.println(dis.readUTF());
		    //发送信息
			OutputStream os = socket.getOutputStream();//得到输出流对象
			DataOutputStream dos = new DataOutputStream(os);//实例化数据输出流对象,发送信息
			dos.writeUTF("服务器端说:"+input.next());	//将信息发送给客户端
			dos.flush();
		}
	}
}

结果:

方法二:利用子线程实现

客户端Client:

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Client {

	public static void main(String[] args) throws Exception {
		Scanner input = new Scanner(System.in);
		Socket socket = new Socket("192.168.23.18",9999); // 实例化一个基于客户端的Socket对象,目标主机和目标主机的端口号,目标主机这里采用本电脑的ip
		ClientReadThread thread = new ClientReadThread(socket);//实例化子线程:用来读取取服务器端信息
		new Thread(thread).start(); //子线程启动
		//由主线程发送数据给服务器端
		while(true) {
			OutputStream os = socket.getOutputStream();//得到输出流对象,用于发送信息
			DataOutputStream dos = new DataOutputStream(os);//实例化数据输出流,将原始Java数据类型写入输出流,应用程序可以使用数据输入流来读取数据
			dos.writeUTF("客户端说:"+input.next());//发送信息给服务器端
		}
		
	}

}

客户端的子线程ClientReadThread:

import java.io.*;
import java.net.*;

public class ClientReadThread implements Runnable {
	private Socket socket;
	public ClientReadThread(Socket socekt) {
		this.socket = socekt;
	}
	public void run() {
		while(true) {
			try {
				//客户端读取服务器端的响应数据
				InputStream is = socket.getInputStream();
				DataInputStream dis = new DataInputStream(is);
				System.out.println(dis.readUTF());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}

服务器端:

import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Server {
	public static void main(String[] args) throws Exception {
		//接收客户端发送的对象信息
		Scanner input = new Scanner(System.in);	
		ServerSocket ssocket = new ServerSocket(9999); //实例化一个基于服务器端的socket对象
		Socket socket = ssocket.accept(); //调用监听功能,侦听9999端口,有信息就直接获得该客户端的socket对象
		ServerReadThread thread = new ServerReadThread(socket);//实例化子线程,用来取客户端发送的信息
		new Thread(thread).start(); //实例化子线程对象,并启动子
		//由主线程来负责发送数据给客户端
		while(true) {
			OutputStream os = socket.getOutputStream();//得到输出流对象
			DataOutputStream dos = new DataOutputStream(os);//实例化数据输出流对象,发送信息
			dos.writeUTF("服务器端说:"+input.next());	//将信息发送给客户端
			
		}
	}
}

服务器端的子线程:

import java.io.*;
import java.net.*;

public class ServerReadThread implements Runnable {
	private Socket socket;
	public ServerReadThread(Socket socket) {
		this.socket = socket;
	}
	public void run() {
		try {
			while(true) {
				// 读取客户端发送过来的数据
				// 通过该socket得到输入流对象
				InputStream is = socket.getInputStream();
				DataInputStream dis = new DataInputStream(is);
				System.out.println(dis.readUTF());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果如下:

6、多个客户端群聊

 这也用得子线程实现

客户端Client:

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class Client {

	public static void main(String[] args) throws Exception {
		Scanner input = new Scanner(System.in);
		Socket socket = new Socket("192.168.23.18",9999); // 实例化一个基于客户端的Socket对象,目标主机和目标主机的端口号,目标主机这里采用本电脑的ip
		while(true) {
			//发送信息
			OutputStream os = socket.getOutputStream();//得到输出流对象,用于发送信息
			DataOutputStream dos = new DataOutputStream(os);//实例化数据输出流,将原始Java数据类型写入输出流,应用程序可以使用数据输入流来读取数据
			dos.writeUTF("客户端说:"+input.next());//发送信息给服务器端
			dos.flush();
			//接收响应数据
			InputStream is = socket.getInputStream();
			DataInputStream dis = new DataInputStream(is);
			System.out.println(dis.readUTF());
		}
		
	}

}

客户端的子线程:ClientReadThread

import java.io.*;
import java.net.*;

public class ClientReadThread implements Runnable {
	private Socket socket;
	public ClientReadThread(Socket socekt) {
		this.socket = socekt;
	}
	public void run() {
		while(true) {
			try {
				//客户端读取服务器端的响应数据
				InputStream is = socket.getInputStream();
				DataInputStream dis = new DataInputStream(is);
				System.out.println(dis.readUTF());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

服务器端:Server

import java.io.*;
import java.net.*;
import java.util.*;
public class Server {
	public static ArrayList<Socket> list = new ArrayList<>(); //收集所有群成员对应的socket对象
	private static Scanner input = new Scanner(System.in);
	
	public static void main(String[] args) throws Exception {
		ServerSocket ssocket = new ServerSocket(9999); //实例化一个基于服务器端的socket对象
		while(true) {
			//服务器负责给每个用户端发送信息
			Socket socket = ssocket.accept(); //调用监听功能,侦听9999端口,有信息就直接获得该客户端的socket对象
			list.add(socket);
			System.out.println("当前在线人数是:"+list.size());
			ServerReadThread thread = new ServerReadThread(socket);//子线程作用就是负责读取发送客户端的信息,并且广播给其它成员客户端
			new Thread(thread).start(); //启动一个子线程
			
		}
	}
}

服务器的子线程:ServerReadThread

import java.io.*;
import java.net.*;
public class ServerReadThread implements Runnable {
	private Socket socket;
	public ServerReadThread(Socket socket) {
		this.socket = socket;
	}
	public void run() {
		try {
			while(true) {
				InputStream is = socket.getInputStream();//获取客户端发来的输入流,socket指的是发送信息的客户端socket对象
				DataInputStream dis = new DataInputStream(is);//转化为数据输入流
				//得到发送信息客户端的实现发送的内容
				String message = dis.readUTF();
				for (Socket currentSocket : Server.list) { //遍历集合中收集的所有成员的socket对象
					if(socket!=currentSocket) { //排除掉自己,因为这条信息本身就是自己发的,没必要再广播给自己了
						OutputStream os = currentSocket.getOutputStream();//得到当前遍历的socket的输出流对象,因为广播就是通过该输出流写出去的
						DataOutputStream oos = new DataOutputStream(os);
						oos.writeUTF(message);//把信息广播发送出去
					}
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

结果:每运行一次Client类,就产生一个用户,

  五,网络编程-基于UDP协议的操作

1、DatagramSocket和DatagramPacket

java.net包中提供了两个类:DatagramSocket和DatagramPacket用来支持UDP通信。这一节先介绍一下 DatagramSocket类,DatagramSocket用于在程序之间建立传送数据报的通信连接。

下DatagramSocket常用的构造方法:

  • DatagramSocket():创建数据报DatagramSocket对象,并将其绑定到本地主机上任何可用的端 口。
  • DatagramSocket(int port):创建数据报DatagramSocket对象,并将其绑定到本地主机上的指定端 口。
  • DatagramSocket(int port, InetAddress laddr):创建数据报DatagramSocket对象,并将其绑定到指定 的本地地址。

DatagramSocket其他的常用方法有:

  • void send(DatagramPacket p):从发送数据报包。
  • void receive(DatagramPacket p):接收数据报包。
  • int getPort():返回DatagramSocket连接到的远程端口。
  • int getLocalPort():返回DatagramSocket绑定到的本地端口。
  • InetAddress getInetAddress():返回DatagramSocket连接的地址。
  • InetAddress getLocalAddress():返回DatagramSocket绑定的本地地址。
  • boolean isClosed():返回DatagramSocket是否处于关闭状态。
  • boolean isConnected():返回DatagramSocket是否处于连接状态。
  • void close():关闭DatagramSocket。

DatagramSocket也实现了AutoCloseable接口,通过自动资源管理技术关闭DatagramSocket。

2、发送端给接收端发送信息:

发送端Sender:

import java.net.*;

public class Sender {
	public static void main(String[] args) throws Exception {
		DatagramSocket socket = new DatagramSocket();
		String content = "hello,好好学习,天天向上!!!";//准备要发送的内容
		System.out.println(content.length()); //18
		System.out.println(content.getBytes().length); //30
		//把要发送的内容和目标主机及端口封装在数据报包对象中
		DatagramPacket packet = new DatagramPacket(content.getBytes(), content.getBytes().length, InetAddress.getByName("127.0.0.1"), 10086);
//		content.getBytes():要发送的字节数据
//		content.getBytes().length:发送内容字节的长度
//		InetAddress.getByName("127.0.0.1"):目的地的ip 
//		10086:目的地主机的端口号
		socket.send(packet);//执行发送操作
		System.out.println("发送成功!!!!");
		
	}

}

接收端:

import java.net.*;

public class Sender {
	public static void main(String[] args) throws Exception {
		DatagramSocket socket = new DatagramSocket();
		String content = "hello,好好学习,天天向上!!!";//准备要发送的内容
		System.out.println(content.length()); //18
		System.out.println(content.getBytes().length); //30
		//把要发送的内容和目标主机及端口封装在数据报包对象中
		DatagramPacket packet = new DatagramPacket(content.getBytes(), content.getBytes().length, InetAddress.getByName("127.0.0.1"), 10086);
//		content.getBytes():要发送的字节数据
//		content.getBytes().length:发送内容字节的长度
//		InetAddress.getByName("127.0.0.1"):目的地的ip 
//		10086:目的地主机的端口号
		socket.send(packet);//执行发送操作
		System.out.println("发送成功!!!!");
		
	}

}

结果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java网络编程是通过使用Java语言来开发网络应用程序的一种技术。斗地主是一种广泛流行的扑克游戏。结合这两者,我们可以实现一个Java网络斗地主游戏。 要编写一个Java网络斗地主游戏,可以分为客户端和服务器端两部分。 客户端负责与用户交互,并通过网络与服务器通信。我们可以使用Java的Swing或JavaFX库来实现游戏的图形用户界面,包括显示玩家的手牌、出牌区等。客户端还需要处理用户的操作,例如出牌、抢地主等,并将这些操作发送到服务器端。 服务器端负责处理客户端的请求,并管理游戏的进程。服务器需要接收客户端的操作,例如出牌、抢地主等,并更新游戏状态。服务器还需要将游戏状态发送给所有客户端,以保持游戏的同步性。服务器可以使用Java的Socket库来与客户端进行通信。 在客户端和服务器之间的通信中,可以使用Java的序列化技术将游戏的状态对象进行序列化和反序列化。这样可以方便地在网络上传输并保持游戏的同步性。 此外,我们还可以使用多线程来处理客户端和服务器端的并发请求。例如,服务器可以为每个客户端分配一个线程来处理其请求,并使用锁来保护游戏状态的访问和修改,以避免竞态条件。 总之,通过使用Java网络编程技术,我们可以实现一个互联网上的斗地主游戏,使得玩家能够通过网络与其他玩家进行对战,享受斗地主的乐趣。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值