반응형
쓰레드
개별작업 및 동시작업은 모두 쓰레드로 만든다.
ChatServer
- 클라이언트의 연결요청을 받으면 소켓을 만들고, 스레드를 생성한다.
- 콜렉션에 연결된 클라이언트들을 저장한다.
ChatServerThread
- 클라이언트와 메세지를 주고받는다.
(클라이언트가 보낸 메세지는 연결된 모든 클라이언트에게 보낸다.)
ChatClient
- 채팅창을 표시
- 입력한 메세지를 서버로 전송
ChatClientThread
- 서버에서 보내 메세지를 받아서 채팅화면에 표시
(메세지를 보내고 있거나, 입력하는 것과 상관없이 메세지 표시를 지원
package net.chat;
import javax.swing.JFrame;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
// 05.04 월5
public class ChatClient extends JFrame {
private JTextField field;
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
JTextArea textArea = new JTextArea();
public ChatClient() {
// 사용할 닉네임을 입력 받기
String nick = JOptionPane. showInputDialog( "닉네임을 입력하세요");
if ( nick == null) {
System. exit(0);
}
try {
// 서버와 통신할 소켓을 생성
socket = new Socket( "192.168.0.5", 1234);
// 서버로 메세지를 보내는 스트림 생성
out = new PrintWriter( socket.getOutputStream(), true);
// 서버에서 보낸 메세지를 읽어오는 스트림 생성
in = new BufferedReader( new InputStreamReader(socket .getInputStream()));
/*
* 입력작업과는 무관하게 읽어오는 작업이 수행되도록 스레드 생성
*/
ChatClientThread t = new ChatClientThread( in, textArea);
t.start();
} catch(IOException e) {
JOptionPane. showMessageDialog( null, "서버와 연결할 수 없습니다.");
System. exit(0);
}
getContentPane().setLayout( null);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(12, 10, 467, 457);
getContentPane().add( scrollPane);
scrollPane.setViewportView( textArea);
field = new JTextField();
field.setBounds(12, 477, 346, 30);
getContentPane().add( field);
field.setColumns(10);
JButton btn = new JButton( "\uC804\uC1A1");
btn.setBounds(370, 477, 109, 30);
getContentPane().add( btn);
// 전송버튼을 클릭하면 메세지를 서버로 전송한다
btn.addActionListener( e->{
// 멤버변수가 아닌것 들은 익명의 내부클래스 안에서는 사용할수 없다.
try {
// 입력필드의 메세지 읽어오기
String message = field.getText();
// 서버로 메세지 보내기
out.println( nick + " : " + message);
field.setText( "");
field.requestFocus();
} catch (Exception ex) {
JOptionPane. showMessageDialog( null, "연결이 끊어졌습니다.");
System. exit(0);
}
});
setVisible( true);
setBounds(200, 200, 509, 554);
setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE );
}
public static void main(String[] args) {
new ChatClient();
}
}
package net.chat;
import java.io.BufferedReader;
import java.io.IOException;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
//05.04 월6
public class ChatClientThread extends Thread {
// 서버가 보낸 메시지를 읽어오는 스트림
private BufferedReader in;
// 서버가 보낸 메세지를 표시할 곳
private JTextArea area;
public ChatClientThread(BufferedReader in, JTextArea area) {
this. in = in;
this. area = area;
}
public void run() {
try {
while( true) {
// 서버가 보낸 메세지 읽어오기
String message = in.readLine();
// jtextArea에 메세지 표시하기
int length = area.getText().length();
// 텍스트의 삽입위치를 설정해주는 것
area.setCaretPosition( length);
area.append( message + "\n");
}
} catch(IOException e) {
JOptionPane. showMessageDialog( null, "연결이 끊어 졌습니다.");
System. exit(0);
}
}
}
package net.chat;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
// 05.04 월1
public class ChatServer {
// 연결된 클라이언트와 통신을 담당하는 Thread를 담을 콜렉션
private ArrayList<ChatServerThread> users = new ArrayList<ChatServerThread>();
public ChatServer() {
try {
ServerSocket server = new ServerSocket(1234);
System. out.println( "서버가 시작되었습니다." );
while ( true) {
System. out.println( "클라이언트의 연결요청 대기중...");
Socket socket = server.accept();
String ip = socket.getInetAddress().getHostAddress();
System. out.println( "[" + ip + "]에서 접속하였습니다.");
// this 사용
ChatServerThread t = new ChatServerThread(this , socket );
users.add( t);
t.start();
}
} catch (IOException e) {
System. out.println( "서버를 시작할 수 없습니다." );
}
}
public static void main(String[] args) {
new ChatServer();
}
public ArrayList<ChatServerThread> getUsers() {
return users;
}
}
package net.chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
//05.04 월4
public class ChatServerThread extends Thread {
private ChatServer chatserver;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ChatServerThread(ChatServer chatServer, Socket socket) {
this. chatserver = chatServer;
this. socket = socket;
}
public void run() {
try {
// 클라이언트가 보낸 메세지 읽을 스트림
in = new BufferedReader( new InputStreamReader(
socket.getInputStream()));
// 클라이언트로 메세지를 보내는 스트림
out = new PrintWriter( socket.getOutputStream(), true);
} catch (IOException e) {
}
try {
while ( true) {
// 클라이언트가 보낸 메세지 읽기
String message = in.readLine();
// 메세지를 연결된 모든 클라이언트에게 보내기
broadcast( message);
}
} catch (IOException ex) {
String ip = socket.getInetAddress().getHostAddress();
broadcast( "<<" + ip + ">>가 나갔습니다." );
chatserver.getUsers().remove( this);
}
}
/*
* ChatServer의 ArrayList에는 클라이언트와 통신을 담당하는 스레드가 여러개 저장되어 있다. ArrayList에서
* 스레드를 하나씩 꺼내서 연결된 클라이언트로 메세지를 전송하도록 한다(sendMessage 이용)
*/
public void broadcast(String message) {
ArrayList<ChatServerThread> users = chatserver.getUsers();
// ArrayList 에서 스레드 꺼내기
for (ChatServerThread t : users) {
// 스레드와 연결된 모든 클라이언트로 메세지 보내기
t.sendMessage( message);
}
}
// 연결된 클라이언트로 메세지 보내기
public void sendMessage(String message) {
out.println( message);
}
}
1. 자료형
기본자료형 - boolean, byte, short, int, long, float, double, char
객체 - 기본자료형 빼고 전부다...
2. 변수
지역변수 - 메소드 안에서 만들어진 변수
public void a(){
int x = 0;
Person p = new Person();
}
매개변수 - 메소드를 실행할때 전달한 값을 담기위해 사용되는 변수
public void a(String name, Car car){}
인스턴스 변수 - 객체의 속성을 담는 변수, 접근제한자를 붙일 수 있다.
public class A{
private int x;
private String y;
private ArrayList Items;
}
클래스변수(static변수)-상수값(변화지 않는 값)을 주로 담아둔다.
public static final int MAX_FILE_UPLOAD_SIZE = 1000000;
3. 배열
- 같은 타입의 값을 여러 개 담을 수 있다.
- 한번 정해진 크기를 변경할 수 없다.
- 콜렉션(Set이나 List)에 비해 사용성이 떨어진다.
String[] names = {"길동", "순신"};
int[] scores = new int[]{10,30,70,90};
Person[] people = new Person[3];
people[0] = new Person();
- length 속성을 사용해서 배열의 길이를 알수 있다.
- Enhanced-for문을 사용해서 배열의 각 요소를 돌아다닐수 있다.
for(String n: names){
//n에 배열의 각 요소가 차례로 담긴다.
//n에 담긴 값을 처리하는 코드...
};
4. 클래스 - 객체
클래스는 설계도다.
클래스는 속성과 기능을 가질 수 있다.
클래스의 속성은 값이다. 적절한 변수를 사용한다.
클래스의 기능은 속성으로서의 값을 조회/변경/사용한다.
클래스의 기능은 적절한 구현코드로 구성된 메소드를 사용한다.
객체는 클래스에 설계된 그대로 메모리에서 생성된 것이다.
객체를 만든 이후에만, 속성에 값을 담거나, 정의된 기능을 사용할 수 있다.
객체의 생성은 대부분 new 키워들를 사용한다.
new 키워드 다음에는 객체 생성된 직후 실행하고 싶은 생성자를 적는다.
Person p = new Person();
Person p = new Person("홍길동", 43, 'A');
참조변수는 생성된 객체의 주소값을 담고 있는 변수다.
참조변수에 담긴 주소값을 사용하면 생성된 객체에 접근할 수 있다.
참조변수를 사용해서 객체의 속성이나 기능에 접근할 때는"."연산자를 사용한다.
Person p = new Person();
p.display()
p.setName("홍길동");
참조변수를 사용해서 객체의 속성과 기능에 접근할 때는 접근제한자의 영향을 받는다.
5. 생성자
객체가 생성될때 실행되는 메소드
생성자는 여러 개 중복 정의할 수 있다.
생성자는 객체가 필요로 하는 값(혹은 객체)를 전달받기 위해서 사용된다.
생성자는 멤버변수(인스턴스변수)를 초기화하기 위해서 사용된다.
6. 상속
부모 클래스의 속성과 기능을 상속받기 위해서 사용한다.
클래스는 부모 클래스를 하나만 가질 수 있다.
특정한 클래스를 상속받은 자식 클래스들은 모두 상속받은 부모클래스류가 된다.
부모 클래스 타입의 참조변수에 자식 클래스의 객체를 담을수 있다.
객체가 생성될 때는 언제나 모든 조상 클래스의 객체들이 먼저생성된다.
생성된 객체는 여러 조상객체들이 계층적 구조로 함께 만들어져 있다.
Object는 모든 객체의 부모객체다.
Object는 최상위 부모객체다.
Object 클래스에 정의된 기능은 모든 객체에서 언제나 사용할 수 있다.
생성된 객체를 참조하는 방법은 여러가지가 있다.
생성된 객체의 어느 부분을 참조하고 있는가에 따라서 사용할 수 있는 기능의 차이가 발생한다.
Iphone p = new IPhone();
//iphone의 기능/속성, Phone의 기능/속성, Object의 기능
Phone p= new IPhone();
//Phone의 기능/속성 Object의 기능 사용가능
Phone p = new Galaxy6();
//Phone의 기능/속성, Object의 기능 사용가능
Object o = new IPhone();
//Object 기능 사용가능
7. 메소드 재정의
부모로부터 물려받은 기능이 사용하기 적합하지 않은 경우 재정의하는것
항상 상속관계/ 구현관계에 있을때만 적용이 가능하다.
부모로부터 물려받은 메소드와 완전히 똑같은 구조를 가진 메소드로 만들어야한다.
재정의된 메소드는 굳이 그 메소드가 재정의된 객체를 참조하지 않아도 실행할 수 있다.
8. 추상화, 인터페이스
추상화는 강제력을 가진다.
추상화는 구현부가 없는 추상메소드를 만들어두는 것이다.
추상화된 부모클래스를 상속받은 자식클래스(구현클래스)는 반드시 추상화되어있는 메소드를 재정의 해야된다.
추상화는 비슷한 기능을 자식클래스에서 동일한 이름으로 구현하도록 강제력을 행사한다.
public abstract Printer{
public abstract void print();
}
public ColorPrinter extends Printer{
public void print(){
......적합한 기능 구현
}
}
인터페이스는 상수와 추상메소드만 가지고 있다.
클래스는 한번에 여러 개의 인터페이스를 구현(상속)할수 있다.
특정한 인터페이스를 구현한 클래스는 반드시 그 인터페이스에서 추상화했던 메소드와 똑같은 이름을 가진 기능이 구현되어 있다.
인터페이스는 규약, 표준으로 사용된다.
9. String, StringBuilder, Wrapper class
String객체는 불변객체다.
String객체의 주요 메소드는 반드시 사용법을 기억하자.
String값이 비교는 반드시 equals()를 사용
StringBuilder와 StringBufer는 문자열이나 다른 값들을 이어붙일 때 사용한다.
Wrapper클래스는 각각의 기본자료형과 대응되는 클래스다.
int값을 바로 담을 수 없는 경우, 대응되는 Integer객체를 지정하면된다.
jdk5.0버전부터는 auto-boxing과 auto-unboxing을 지원한다.
10. 콜렉션(Set, List, Map)
콜렉션은 자바의 자료구조 프레임워크다.
콜렉션 객체를 사용하면 여러 개를 담을 수 있다.
콜렉션 객체는 용량이 가변적으로 변한다.
콜렉션 객체를 만들때는 Generic표기법으로 저장할 값(객체)의 타입을 지정해야 한다.
Set계열의 객체에는 중복된 값(객체)이 저장되지 않는다.
List계열의 객체에는 담은 순서대로 다시 꺼낼 수 있다.. index가 존재한다.
콜렉션의 주요 메소드
add(E e) - 저장하기
remove(Object o) - 지우기
size() - 저장된 갯수 조회하기
contains(Object o) -포함하고 있는지 확인하기
isEmpty() - 비어있는지 확인하기
clear() - 전부 지우기
get(int index) - 지정된 위치에 저장된거 가져오기
remove(int index) - 지정된 위치에 저장된거 지우기
add(int index, E e) - 지정된 위치에 저장하기
콜렉션에 저장된 값(객체)은 Enhanced-for 문을 사용하면 모두 꺼낼 수 있다.
Map은 <key, value>의 단위로 값(객체)을 저장한다.
key의 타입과 value의 타입을 Map객체생성할 때 Generic 표기법으로 지정해야 한다.
Map객체의 주요메소드
put(K k, V v) -Map 객체에 담기
remove(K k) - 지정된 key에 해당하는 값(객체) 지우기
V get(K k) - 지정된 key에 해당하는 값(객체) 꺼내기
size() - 저장된 값(객체)의 갯수 조회하기
isEmpty() - 비어있는지 확인하기
clear() - 전부 지우기
11. io, thread, network
# 경매
서버
- 상품등록
- 경매시작(broadcast) 누르면 상품이름과 최저입찰가 클라이언트에 전달
- 누군가 얼마를 입찰했는지 다른 클라이언트들에게도 표시
- 입찰 후 일정시간동안 아무도 입찰하지 않으면 낙찰
1. 서버
- 경매상품등록
- 경매 시작 알림
- 입찰가격을 모든 클라이언트에 전송
2. 클라이언트
- 경매물품이 표시
- 경매에 입찰을 할수 있어야 함
- 다른 사람의 입찰가격이 표시되어야 함
# 뱅킹
- 계좌개설, 입금, 출금, 해지
1. 서버
- 계좌의 개설/ 입금/ 출금/ 해지 기능을 지원
- 개설된 계좌정보를 저장
2. 클라이언트
- 신규 계좌 개설화면
- 입금/ 출금/ 해지/ 조회 화면
반응형