>  기사  >  Java  >  Java를 처음 배우는 초보자를 위한 메모 (5)

Java를 처음 배우는 초보자를 위한 메모 (5)

黄舟
黄舟원래의
2016-12-20 13:49:451092검색


Java에 대한 기본 지식을 추가하세요.

1. 예외
Java의 예외 처리는 델파이와 동일합니다. 예외 발생을 고의로 피하는 것이 아니라 발생한 후에 이를 해결하는 것입니다.
델파이의 예외 처리는 간단히 말해서 다음 문장

Try
Except//예외가 발생하면 여기로 옮겨져 실행됩니다
마지막으로//예외가 발생하든 안 일어나든 여기로 옮겨져 실행됩니다


이와 마찬가지로 Java의 예외 처리의 기본 형태는 다음과 같습니다
try{
}catch(ExceptionType1 e){
file://예외 1 처리
}catch(ExceptionType2 e) {
file://예외 2 처리
throw(e)//예외를 발생시킵니다. 이는 Delphi의 raise와 동일합니다
}

추가할 사항은 대부분의 예외에 대해 예외를 포착하는 프로그램이 아닌 정상적으로 실행되는 프로그램에서 명시적으로 발생시키려는 경우 Java 컴파일러에서는 발생하려는 예외를 미리 선언하도록 요구합니다. 이 작업은 throws로 완료됩니다.

2. Java 입력 및 출력 스트림
2.1 출력
System.out.PRint 파일://여기 출력은 정적입니다. method
System.out.println
System.err.print file://err도 out과 같은 표준 출력입니다. 차이점은 아직 모르겠습니다
System.err.println
2.2 입력
System.in.read()
2.3 파일 작업
주석이 달린 몇 가지 예만으로도 충분합니다.
첫 번째는 파일에 대한 기본 정보를 표시하는 프로그램입니다

import java.io.*;//Load io 관련 클래스
class fileinfo{
file://note , main 함수는 정적 메소드여야 합니다.

public static void main(String args[])throws IOException{
File fileToCheck;//파일 객체를 사용하여 인스턴스 생성
if(args.length> ;0) {
for (int i=0;ifileToCheck=new File(args[i]);//파일 객체를 위한 공간 할당
info( fileToCheck);/ /여기에 참조된 정보는 정적 메서드 멤버여야 합니다
}
}
else{
System.out.println("no file available");
}
}

public static void info(File f)가 IOException을 발생시킵니다.{
System.out.println("Name:"+f.getName());
System.out.println(" 경로:"+f .getPath());
if (f.exists()){
System.out.println("파일이 있습니다.");
System.out.print((f .canRead()? " and is Readable":""));//결정 함수, 조건이 충족되면 전자를 출력하고, 그렇지 않으면 후자를 출력합니다
System.out.print((f.canWrite() ?"쓰기 가능":" "));
System.out.print(".");
System.out.println("파일은"+f.length()+"바이트입니다." );
}
else{
System.out.println("파일이 존재하지 않습니다.");
}
}
}

두 번째 예 전화 정보를 저장하는 작은 파일 프로그램으로 사용자가 이름과 전화번호를 입력하면 프로그램이 이를 Phone.numbers 파일에 저장하고 FileOutputStream

import java.io.*;
클래스 폰{
static FileOutputStream fos;
public static final int lineLength=81;
public static void main(String args[])throws IOException{
byte[]phone=new byte[lineLength];
byte[] name=new byte[lineLength];
int i;
fos=new FileOutputStream("phone.numbers");
while(true){
System.err.println("이름을 입력하세요(종료하려면 'done' 입력).");
readLine(name);
if ("done".equalsIgnoreCase(new String(name,0,0, 4))){
break;
}
System.err.println("전화번호를 입력하세요");
readLine(phone);
for (i=0;phone[ i]!=0;i++){
fos.write(phone[i]);
}
fos.write(′,′);
for (i=0;name[i ]!=0;i++){
fos.write(name[i]);
}
fos.write(′ ′);
}
fos.close();
}

private static void readLine(byte line[])throws IOException{
int i=0,b=0;
while((i<(lineLength-1))&&( (b=System.in.read()) !=′ ′)){
line[i++]=(byte)b;
}
line[i]=(byte)(0);
}
}

2.4 스트림
은 두 개에 불과합니다.
작성하기 위한 출력 스트림
읽기 위한 입력 스트림
java.io 패키지의 입력 및 출력 스트림
1.FileInputStream 및 FileOutputStream 노드 스트림
2.BufferedInputStream 및 BufferedOutputStream 필터링된 스트림
3.DataInputStream 및 DataOutputStream 향상된 필터링된 스트림
4.PipedInputStream 및 PipedOutputStream 스트림 스레드용

스트림의 개념을 이해했다면 이제 소켓 학습을 시작할 수 있습니다. 어제 소켓의 역할에 대해 이야기했습니다.

이제 간단한 통신 프로그램을 만들어보겠습니다. 소켓에 대한 이해가 풍부합니다. 프로그램은 클라이언트(RemoteFileClient)와 서버(RemoteFileServer)로 구성됩니다. 클라이언트는 서버에 있는 파일 정보를 읽으라는 요청을 보냅니다. 그리고 해당 파일 정보를 클라이언트에 전달합니다.

먼저 RemoteFileClient 클래스를 만듭니다.
import java.io.*;//java.io 패키지 스트림을 읽고 쓰는 도구를 제공하며 TCP와도 호환됩니다. 소켓과 통신하는 유일한 방법
import java.net.*;//java.net 패키지는 소켓 기능을 제공합니다.

공용 클래스 RemoteFileClient {
protected String hostIp;
protected int hostPort;
protected BufferedReader 소켓 리더;//데이터 읽기를 담당하는 개체
protected PrintWriter 소켓Writer;//데이터 쓰기를 담당하는 개체

file:// 클래스의 생성자에는 두 개의 매개 변수가 있습니다: IP 주소 생성자는 이를 인스턴스 변수
public RemoteFileClient(String aHostIp, int aHostPort) {
hostIp = aHostIp;
hostPort = aHostPort;}
public static void main(String[] args) {
}
file://원격 서버에 연결
public void setUpConnection() {
}
file: // 원격 서버가 파일 정보를 요청합니다
public String getFile(String fileNameToGet) {
}
file://원격 서버에서 연결을 끊습니다
public void teeDownConnection() {
}
}

먼저 main() 구현
public static void main(String[] args) {
RemoteFileClient RemoteFileClient = new RemoteFileClient("127.0.0.1", 3000);// 디버깅의 편의를 위해 로컬 서버를 원격 서버
remoteFileClient.setUpConnection();//Connect로 처리합니다. setUpConnection은 비정적 변수이므로 직접 사용할 수 없습니다. 인스턴스를 생성한 후 참조해야 합니다.
String fileContents =
remoteFileClient. getFile("RemoteFile .txt");//읽기

remoteFileClient.tearDownConnection();//연결 끊기

System.out.println(fileContents);//읽은 내용 출력
}

단계는 매우 명확합니다. 그러면 연결, 읽기 및 연결 해제가 어떻게 별도로 구현되는지 살펴보겠습니다.
1.Connection
public void setUpConnection() {
try {
소켓 클라이언트 = new Socket(hostIp, hostPort);//소켓 객체 생성

OutputStream outToServerStream=client.getOutputStream();
InputStream inFromServerStream=client.getInputStream();
socketReader = new BufferedReader(new InputStreamReader(inFromServerStream));
file://소켓의 InputStream을 BufferedReader로 래핑하여 스트림의 행을 읽을 수 있도록 합니다.

socketWriter = new PrintWriter(outToServerStream);
file:// 서버에 파일 요청을 보낼 수 있도록 소켓의 OutputStream을 PrintWriter로 래핑합니다.

} catch (UnknownHostException e) {
System.out.println("소켓 연결 설정 오류: " +hostIp + ":" +hostPort)의 알 수 없는 호스트;
file://소켓 객체 생성 오류에 대한 예외 처리
} catch(IOException e) {
System.out.println("오류 설정 업 소켓 연결: " + e);
file://IO 오류에 대한 예외 처리
}
}

2. 읽기
public String getFile(String fileNameToGet) {
StringBuffer fileLines = new StringBuffer();//StringBuffer 객체도 String 객체이지만 이 객체보다 더 유연합니다. 여기서는 읽은 내용을 저장하는 데 사용됩니다.

try {
socketWriter .println(fileNameToGet);
socketWriter.flush();//socketWriter에 파일 저장 주소를 출력한 후 버퍼를 비우고 이 주소를 서버로 보냅니다

String line = null;
while ((line = 소켓Reader.readLine()) != null)
fileLines.append(line + " ");
file://서버에 전송되었으므로 모두 기다려야 합니다. 여기서 프로그램은 서버가 필요한 파일 콘텐츠를 전달하는 것을 기다리는 것입니다.
} catch (IOException e) {
System.out.println("Error reading from file: " + fileNameToGet);
}

return fileLines.toString();//버퍼의 내용을 문자열로 변환하고
}

Disconnect
public void를 반환하는 것을 잊지 마세요. teaDownConnection() {
try {
socketWriter.close();
socketReader.close();
} catch(IOException e) {
System.out.println("해체하는 동안 오류가 발생했습니다. 소켓 연결: " + e);
}
}

tearDownConnection() 메서드는 소켓의 InputStream 및 OutputStream에서 생성한 BufferedReader 및 PrintWriter만 닫습니다. 이렇게 하면 소켓에서 얻은 기본 스트림이 닫히므로 가능한 IOException을 잡아야 합니다

자, 이제 클라이언트 프로그램을 만드는 단계를 요약할 수 있습니다
1. 머신의 IP를 사용합니다. 포트 번호로 소켓을 인스턴스화합니다(문제가 있는 경우 예외 발생).
2. 읽기 및 쓰기를 위해 소켓에서 스트림을 가져옵니다.
3. 스트림을 BufferedReader/PrintWriter의 인스턴스로 압축합니다.
4. 특히 Writer Send에서 전송합니다. 파일 주소 정보를 서버로 보내고, 서버에서 파일 정보를 리더에서 읽어옵니다
5. 오픈 스트림을 닫습니다.

다음은 RemoteFileClient 코드 목록입니다

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

public class RemoteFileClient {
protected BufferedReader 소켓 리더;
protected PrintWriter 소켓Writer;
protected String hostIp;
protected int hostPort;

public RemoteFileClient(String aHostIp, int aHostPort) {
hostIp = aHostIp;
hostPort = aHostPort;
}
public String getFile(String fileNameToGet) {
StringBuffer fileLines = new StringBuffer();

try {
socketWriter.println(fileNameToGet);
소켓Writer.flush();

문자열 라인 = null;
while((line = 소켓Reader.readLine()) != null)
fileLines.append(line + " ");
} catch(IOException e) {
System.out.println("파일 읽기 오류: " + fileNameToGet);
}

return fileLines.toString();
}
public static void main(String[] args) {
RemoteFileClient RemoteFileClient = new RemoteFileClient("127.0.0.1", 3000);
remoteFileClient.setUpConnection( );
String fileContents = remoteFileClient.getFile("RemoteFile.txt");
remoteFileClient.tearDownConnection();

System.out.println(fileContents);
}
public void setUpConnection() {
시도 {
소켓 클라이언트 = 새 소켓(hostIp, hostPort);

OutputStream outToServerStream=client.getOutputStream();
InputStream inFromServerStream=client.getInputStream( );
socketReader = new BufferedReader(new InputStreamReader(inFromServerStream));
socketWriter = new PrintWriter(outToServerStream);

} catch(UnknownHostException e) {
System.out.println( "소켓 연결 설정 오류: " +hostIp + ":" +hostPort)에서 알 수 없는 호스트;
} catch(IOException e) {
System.out.println("소켓 연결 설정 오류: " + e );
}
}
public void teaDownConnection() {
try {
socketWriter.close();
socketReader.close();
} catch(IOException e ) {
System.out.println("소켓 연결 해제 오류: " + e);
}
}
}

好了,现在来看服务器端的程序怎么写.
创建RemoteClientServer类:
import java.io.*;
import java.net.*;

public class RemoteFileServer {
protected int listeningPort = 3000;
public static void main(String[] args) {
}
public void acceptConnections() {
}
public void handlerConnection(Socket receivedConnection) {
}
}

跟客户机中一样, 首先导入 java.net 的 java.io.的连接。缺省情况下,端口是 3000。
acceptConnections()将答应客户机连接到服务器
handleConnection()负责与客户机소켓容发送到客户机。

首先看main()

public static void main(String[] args) {
RemoteFileServer server = new RemoteFileServer();
server.acceptConnections();
}
不常简单,因为主函数无不是让服务器进入监听状态, 所以直接调用 acceptConnection().需要注는 是, 必须先创建RemoteFileServer()의 용도,而不是直接调사용.

那么服务器是怎样通过acceptConnection( )来监听客机的连接呢?并且假如兼听到了,又怎样处理呢?我们来看
public void acceptConnections() {
try {
ServerSocket server = new ServerSocket(list 엔포트);/ /同客户机的Socket对应, 服务器端, 우리는ServerSocket对象,参数是兼听的端口号
Socket receivedConnection = null;//创建一个客户端的Socket变weight,以接收从客户端监听到的소켓
while (true) {
incomingConnection = server.accept();//调用该 ServerSocket 의 accept() 来告诉它开始侦听,
handleConnection(incomingConnection);
}
file://不断监听直到来了一个连接请求,然后交由handleConnection处리
} catch (BindException e) {
System.out.println("포트에 바인딩할 수 없습니다. " + listeningPort);
} catch (IOException e) {
System.out.println("다음 포트에서 ServerSocket을 인스턴스화할 수 없습니다: " + listeningPort);
}
}

无论何时假如创建了一个无法绑定到指定端口 (可能是因为别的什么控 제조사了该端了) 의 ServerSocket, Java 代码道将抛出一个错误。所以这里我们必须捕捉可能的 BindException입니다. 1개는 IOException이며, ServerSocket에서 上接受连接时, 它就会被抛可以以过用毫秒数调用 setSoTimeout() 来为 accept()를 사용합니다.设置超时,以避免实际长时间的等待. setSoTimeout() 将使 accept()를 사용하여 IOException

을 사용하는 경우handleConnection()中,这时已经连接到了客户端的Socket,要从该Socket中读取客户端的请求并且响应。

public voidhandleConnection(Socket receivedConnection) {
try {
OutputStreamoutputToSocket=incomingConnection.getOutputStream();
InputStream inputFromSocket=incomingConnection.getInputStream();

file://首先获取同Socket상호关联적流outputToSocket과InputStream
file://其中outputToSocket是要返回给客户端Socket적류
file://InputStream是客户端发来这里就是文件路径,即"RemoteFile.txt"

BufferedReader streamReader =
new BufferedReader(new InputStreamReader(inputFromSocket));

file://首先要将InputStream转换到BufferedReader中

FileReader fileReader = new FileReader(new File(streamReader.readLine()));
file://BufferedReader에서 파일 경로를 읽고 새 개체를 만듭니다. FileReader

BufferedReader bufferedFileReader = new BufferedReader(fileReader) ;

file://BufferedReader 객체를 다시 생성합니다. 이번에는 파일의 내용을 읽습니다.

PrintWriter streamWriter =
new PrintWriter(OutputStream);

file://은 클라이언트에 파일 정보를 보낼 수 있도록 Socket의 outputToSocket 스트림을 PrintWriter로 래핑합니다.

String line = null;
while ((line = bufferedFileReader.readLine()) != null ) {
streamWriter.println(line);
}
file://bufferedFileReader에서 파일 정보를 읽어와 streamWriter를 통해 클라이언트에 출력

fileReader.close(); >streamWriter.close(); // 소켓의 두 스트림이 닫히는 순서에 주의하세요
streamReader.close()
file://이 완료된 후 모든 스트림을 닫습니다

} catch ( 예외 e) {
System.out.println("클라이언트 처리 오류: " + e);
}
}

닫는 순서에 주의하세요. 모든 작업이 완료된 후 스트림, streamWriter 종료는 streamReader 종료보다 먼저 수행됩니다. 이것은 우연이 아닙니다. 닫는 순서가 바뀌면 클라이언트는 어떤 파일 정보도 얻지 못합니다. 디버깅하여 볼 수 있습니다. 이유는 streamWriter를 닫기 전에 streamReader를 닫으면 아무것도 되지 않기 때문입니다. streamWriter에 기록되었지만 채널을 통과할 수 있는 데이터가 없습니다(채널이 닫혀 있음). 그런데 이상한 점은 이전 streamWriter.println()에서 이미 출력하지 않았나요? 닫혀 있습니까? 클라이언트에 대한 정보 출력에만 도달할 수 있습니까?
streamWriter.close();를 차단하려고 했는데 채널이 닫히지 않아서 발생한 것일 수 있습니다. 특정 순서로 정상적으로 채널을 닫아야만 통신 데이터 전송이 완료될 수 있습니다. 그렇지 않으면 클라이언트가 정보를 수신하지 못합니다.

마지막으로 서버 측 프로그램을 만드는 단계를 요약합니다
1 . 들어오는 클라이언트 연결을 수신할 포트(예: 프로그램의 3000)를 사용하여 ServerSocket을 인스턴스화합니다(문제가 있는 경우 예외 발생).
2. 루프에서 ServerSocket의 accept()를 호출하여 연결을 수신합니다.
3. 읽기 및 쓰기 작업을 위해 클라이언트의 소켓 스트림을 가져옵니다.
4. 클라이언트의 스트림을 읽고 씁니다. 소켓
6. 오픈 스트림을 닫고(Writer를 닫기 전에 Reader를 닫지 마십시오) 통신을 완료합니다.

다음은
RemoteFileServer

가져오기 코드 목록입니다. java.io.* ;
import java.net.*;

public class RemoteFileServer {
int listeningPort;
public RemoteFileServer(int aListenPort) {
listenPort = aListenPort;
}
public void acceptConnections() {
try {
ServerSocket 서버 = new ServerSocket(listenPort);
소켓 receivedConnection = null;
while(true) {
incomingConnection = server.accept() ;
handleConnection(incomingConnection);
}
} catch(BindException e) {
System.out.println("포트에 바인딩할 수 없습니다. " + listeningPort);
} catch (IOException e) {
System.out.println("다음 포트에서 ServerSocket을 인스턴스화할 수 없습니다: " + listeningPort);
}
}
public void handlerConnection(Socket receivedConnection) {
시도 {
OutputStreamoutputToSocket=incomingConnection.getOutputStream();
InputStream inputFromSocket=incomingConnection.getInputStream();

BufferedReader streamReader = new BufferedReader(new InputStreamReader(inputFromSocket));

FileReader fileReader = new FileReader(new File(streamReader.readLine()));

BufferedReader bufferedFileReader = new BufferedReader(fileReader);
PrintWriter streamWriter = new PrintWriter(outputToSocket);
String line = null ;
while ((line = bufferedFileReader.readLine()) != null) {
streamWriter.println(line);
}

fileReader.close() ;
streamWriter .close();
streamReader.close();
} catch(예외 e) {
System.out.println("클라이언트 처리 오류: " + e);
}
}
public static void main(String[] args) {
RemoteFileServer server = new RemoteFileServer(3000);
server.acceptConnections();
}
}

자, 드디어 소켓을 시작하게 되었습니다

위 내용은 자바 초보를 위한 메모(5) 내용입니다. 더 자세한 내용은 PHP 중국어를 참고해주세요. 홈페이지(www.php.cn)!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.