二十九、Java语言之网络编程


第1关:Server端监听


任务描述
在本关中,你将被要求在Server端(服务器)监听客户端的连接。

相关知识
Socket编程
两台机器建立一个双向的网络连接实现数据交换,这个双向链路的一端称为一个Socket。它使用TCP协议提供了两台计算机之间的通信机制,客户端程序创建一个套接字,并尝试连接服务器的套接字。

两台计算机之间使用套接字建立TCP连接的一般步骤:

服务器实例化一个 ServerSocket 对象,表示通过服务器上的端口通信。
服务器调用 ServerSocket 类的 accept() 方法,该方法将一直等待,直到客户端连接到服务器上给定的端口。
服务器正在等待时,一个客户端实例化一个 Socket 对象,指定服务器名称和端口号来请求连接。Socket 类的构造函数试图将客户端连接到指定的服务器和端口号。如果通信被建立,则在客户端创建一个 Socket 对象能够与服务器进行通信。
在服务器端,accept() 方法返回服务器上一个新的 socket 引用,该 socket 连接到客户端的 socket。
Java针对Socket编程提供的类
ServerSocket类
服务器应用程序通过使用java.net.ServerSocket类以获取一个端口,并且侦听客户端请求。

该类中的主要方法:

在这里插入图片描述

Socket类
java.net.Socket类是客户端和服务器用来互相沟通的套接字。客户端通过实例化获取一个Socket对象,而服务器则通过ServerSocket类的accept()方法的返回值获得一个 Socket 对象。

该类中的主要方法:
在这里插入图片描述

DatagramSocket类
DatagramSocket类实现了一个发送和接收数据报的socket,传输层协议使用UDP,不能保证数据报的可靠传输。DataGramSocket主要有send, receive和close三个方法。

该类中的主要方法:
在这里插入图片描述

SocketAddress
SocketAddress提供了一个socket地址,不关心传输层协议。这是一个虚类,由子类来具体实现功能、绑定传输协议。它提供了一个不可变的对象,被socket用来绑定、连接或者返回数值。

InetSocketAddress
InetSocketAddress实现了IP地址的SocketAddress,也就是有IP地址和端口号表达Socket地址。如果不制定具体的IP地址和端口号,那么IP地址默认为本机地址,端口号随机选择一个。

编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:

端口号为6000。
监听客户端的连接。
结束时关闭各个套接字。
评测说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

测试输入:

预期输出:

connected!

代码实现

package step1;

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

public class Server {
	public ServerSocket serverSocket;
	public Socket socket;
	public void start() {
		try {
			Client client = new Client();
			/********** Begin *********/
            serverSocket = new ServerSocket(6000);
            client.start();    //启动客户端
            socket = serverSocket.accept();
            serverSocket.close();
            socket.close();
			/********** End *********/
			client.stop();	//关闭客户端
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
}

第2关:Client端消息发送


任务描述
在本关中,你将被要求在Client端(客户端)向服务器发送字符串I am Client!消息。

相关知识
流的含义
流是一个抽象的概念。当Java程序需要从数据源读取数据时,会开启一个到数据源的流。数据源可以是文件,内存或者网络等。同样,当程序需要输出数 据到目的地时也一样会开启一个流,数据目的地也可以是文件、内存或者网络等。

流的目的
流的创建是为了更方便地处理数据的输入输出。

流的分类
流分为字节流和字符流。字节流也称为原始数据,需要用户读入后进行相应的编码转换。而字节流的实现是基于自动转换的,读取数据时会把数据按照JVM的默认编码自动转换成字符。

Java中I/O流与Socket的结合运用
Java中的字节流由InputStream和OutputStream处理,而字符流由Reader和Writer处理。Reader和Writer是Java后加入的处理类,目的是让数据的处理更加方便。

下面是一个客户端向服务器发送字符串Hello World的部分关键代码:

Socket socket=new Socket("127.0.0.1", 1000);
OutputStream outputStream=socket.getOutputStream();
outputStream.write("Hello World".getBytes());

上述Java代码完成了三件事:

根据IP地址与端口与服务器进行连接。
创建OutputStream类的对象outputStream,并得到Socket类的对象socket的输出流。
利用对象outputStream向服务器发送字符串Hello World,利用getBytes()方法将字符串转化为字节数组以便向服务端传递信息。
不要随便关闭对象outputStream,否则会造成对象socket也被关闭。如果只是想关闭对象socket的输出流,使用对象socket的shutdownOutput()方法。

编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:

创建OutputStream类的对象,向服务器发送字符串I am Client!。
评测说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

本题没有测试样例,平台将比对同学们的程序输出的内容与标准答案。

代码实现

package step2;

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

public class Client {
	private Socket socket;
	private OutputStream socketOutputStream;
	public void start() {
		try {
			socket = new Socket("localhost",6000);
			/********** Begin *********/
            socketOutputStream = socket.getOutputStream();
            socketOutputStream.write("I am Client!".getBytes());


			/********** End *********/
			socket.shutdownOutput();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	public void stop() {
		try{
			socket.close();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
}

第3关:一次完整通信


任务描述
在本关中,你将被要求在客户端向服务端发送一条消息,同时接收服务端返回的一条消息,从而完成一次完整的通信。

相关知识
Java中InputStream类与Socket的结合运用
下面是一个客户端接收服务器发送的消息的部分关键代码:

Socket socket=new Socket("127.0.0.1", 1000);
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1000];
int length = inputStream.read(bytes);
String string = new String(bytes, 0, length);
System.out.print("Client has recevied: " + string);
inputStream.close();

上述Java代码完成了三件事:

根据IP地址与端口与服务器进行连接。
使用InputStream类创建对象inputStream,并得到Socket类的对象socket的输入流。
利用read()方法读取服务端发来的字节数组消息,并利用String类转化成字符串输出至显示器。
编程要求
本关的编程任务是补全右侧代码片段中Begin至End中间的代码,具体要求如下:

relation()方法中填写接收服务端消息并输出的相关代码。(输出函数已给出,请补全!)
start()方法中填写向服务器发送消息的相关代码,发送的消息为字符串I am Client!。
评测说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。

本题没有测试样例,平台将比对同学们的程序输出的内容与标准答案。

代码实现

package step3;

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

public class Client {
	private Socket socket;
	private OutputStream socketOutputStream;
	private InputStream socketInputStream;
	public void relation() {
		try{
			/********** Begin *********/
            socketInputStream = socket.getInputStream();
            byte[] bytes = new byte[1000];
            int length = socketInputStream.read(bytes);
            String serverData = new String(bytes,0,length);
            System.out.print("Client has recevied: " + serverData);

			/********** End *********/
			socket.shutdownInput();
		}
		catch(IOException e) {
			e.printStackTrace();
		}
	}
	public void start() {
		try {
			socket = new Socket("localhost",6000);
			/********** Begin *********/

            socketOutputStream = socket.getOutputStream();
            socketOutputStream.write("I am Client!".getBytes());

			/********** End *********/
			socket.shutdownOutput();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	public void stop() {
		try {
			socket.close();
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
}
  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java网络编程是指使用Java语言进行网络编程,包括Socket、TCP/UDP、IO/NIO、HTTP协议、JDBC、RMI、Java的安全框架等知识。Java网络编程可以实现不同计算机之间的数据通信,使得计算机之间可以互相传输数据。Java网络编程的主要目的是实现客户和服务器之间的数据通信,其中客户和服务器可以在同一台计算机上,也可以在不同的计算机上。Java网络编程的主要步骤包括创建Socket对象、建立连接、发送数据、接收数据等。下面是一个简单的Java网络编程的例子: ```java import java.net.*; import java.io.*; public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("localhost", 8080); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.println("Hello, world!"); String response = in.readLine(); System.out.println("Server response: " + response); } } ``` ```java import java.net.*; import java.io.*; public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8080); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { out.println(inputLine); } } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请你吃茶去

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值