반응형

이번시간엔 안드로이드를 이용한 달력 만드는 방법을 포스팅 해보려고한다. 솔직히 구글, 네이버쪽을 쭉 보면서 많은 도움을 받았다. 근데 내가 찾았던 블로그 명이 기억나지않아서 출저가 어딘지에 대해 알리지 못하는 거에 대해선 양해를 구하고 싶다.


1. activity_main.xml Text 설정

API 23으로 설정해주면 대강 이런식으로 나온다. 달력은 지니모션 돌려보면 다 나오니깐 너무 신경쓰지 않는다. 내가 사용한 코드는 아래와 같다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:background="#FFFFFFFF"
>

<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10px"
android:layout_marginLeft="10px"
android:layout_marginRight="10px"
>

<Button
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="PRE"
android:id="@+id/pre"
android:layout_weight="1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="today"
android:id="@+id/today"
android:layout_weight="3"
android:textColor="#FF000000"
android:gravity="center_horizontal|center_vertical"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="NEXT"
android:id="@+id/next"
android:layout_weight="1"
/>

</LinearLayout>

<TableLayout
android:id="@+id/week"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="true"
android:stretchColumns="true"
android:background="#FF8DC701"
android:layout_marginLeft="10px"
android:layout_marginRight="10px"
>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="일"
android:textColor="#FFFF0000"

android:gravity="center_horizontal" />
<TextView
android:text="월"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:textColor="#FF000000"
android:layout_height="wrap_content"/>
<TextView
android:text="화"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:textColor="#FF000000"
android:layout_height="wrap_content"/>
<TextView
android:text="수"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:textColor="#FF000000"
android:layout_height="wrap_content"/>
<TextView
android:text="목"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:textColor="#FF000000"
android:layout_height="wrap_content"/>
<TextView
android:text="금"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:textColor="#FF000000"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="토"
android:textColor="#FF0000FF"
android:gravity="center_horizontal"/>
</TableRow>
</TableLayout>

<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/table"
android:background="#FFF6F3A4"
android:layout_marginLeft="10px"
android:layout_marginRight="10px"
/>
</LinearLayout>

달력이다 보니 좀 긴감이 없지않아 있지만 이정도가 딱 맞는거 같다. 색깔이나 이런부분은 내 컴퓨터 사양과 맞지 않는 부분이 많아서 내가 색깔을 이것저것 입혀봐서 괜찮다 싶은 거로 설정했다. 이 코드 복사해서 쓰는거는 상관없지만 색깔맞추려면 본인 컴퓨터 사양에 맞게 설정해야 될것이다.(맥북기준)



2. Main_Activity.java 코드 

package com.example.gunjoolee.calendar;

import java.util.Date;
import java.util.Vector;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
public class MainActivity extends Activity {
/** Called when the activity is first created. */

Vector vec;
int firstDay;

int totDays;
int iYear;
int iMonth;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Date today = new Date(); ->오늘날짜
iYear = today.getYear(); ->년도
iMonth = today.getMonth(); ->달 수

vec = new Vector();
TableLayout table = (TableLayout)findViewById( R.id.table );
for( int i = 0 ; i < 6 ; i++ ){
TableRow tr = new TableRow( this );
for( int j = 0 ; j < 7 ; j++ ){
TextView tv = new TextView( this );

if( j == 0 )
tv.setTextColor( Color.RED );
else if( j == 6 )
tv.setTextColor( Color.BLUE ); -> 테이블레이아웃쪽 달력설정

else
tv.setTextColor( Color.BLACK );

tv.setGravity( Gravity.CENTER_HORIZONTAL );

tr.addView( tv );
vec.add( tv );
}
table.addView( tr );
}

table.setStretchAllColumns( true );

table = (TableLayout)findViewById( R.id.week );
table.setStretchAllColumns( true );

setCalendar( iYear, iMonth );

Button btn = (Button)findViewById( R.id.pre ); -> pre 버튼 설정
btn.setOnClickListener( new Button.OnClickListener(){

public void onClick(View v) {

iMonth--;
setCalendar( iYear, iMonth );

}
});

btn = (Button)findViewById( R.id.next ); ->next 버튼 설정
btn.setOnClickListener( new Button.OnClickListener(){

public void onClick(View v) {

iMonth++;
setCalendar( iYear, iMonth );

}
});
}

private void setCalendar( int year, int month ){


Date date = new Date();
date.setYear( year );
date.setMonth( month );
date.setDate( 1 );
firstDay = date.getDay();

totDays = 31;
for( int i = 29 ; i <= 32 ; i++ ){
date.setDate( i );
if( date.getDate() == 1 ){ ->달이 30일인지, 31일인지 설정
totDays = i - 1;
break;
}
}

Log.i("mylog", firstDay + " " + totDays );
date = new Date();
date.setYear( year );
date.setMonth( month );

iYear = date.getYear();
iMonth = date.getMonth();

TextView tvToday = (TextView)findViewById( R.id.today ); ->년,월,날짜설정
tvToday.setText( (iYear + 1900) + "년" + (iMonth + 1) + "월");



for( int i = 0 ; i < vec.size() ; i++ ){
((TextView)vec.get( i )).setText("");
}

int iDate = 1;
for( int i = firstDay ; i < firstDay + totDays; i++ ){

((TextView)vec.get( i )).setText( String.valueOf( iDate++ ) );
}

}
}

달력 java코드이다. 구글이나 네이버쪽에서 참고한 코드인데 출저가 어디였는지 기록해놓지 못해서 아쉽다. 아무튼 이런식으로 짜게되면 만들고자하는 대략의 코드가 나온다. 책에도 많이 나와있고 인터넷에도 많이 도는 코드니까 외우려고 하지말았으면 좋겠다. 


3. 실행

저렇게 디자인을 다하고 저걸 그대로 실행시켜보면 다음과 같은 결과가 얻어졌다. 


결과가 좀 작게나와서 아쉽지만 PRE, NEXT버튼 누르면 아주 잘넘어갈것이다. 만약 이번년도 달력만 만들고 싶으면 자바코드에서 break문 걸고 코드 수정하면 이번년도 달력만 만들 수 있다.

반응형
블로그 이미지

만년필석사

,
반응형

이번시간엔 안드로이드 회원가입, 로그인 프로그램에 대해 포스팅 해보려고 한다. 보통 우리가 어떤 사이트에서 무언가의 대한 정보를 보기 위해 회원가입을 많이 한다. 근데 이게 어떤 원리인지 참 궁금한 점이 많았다. 그래서 안드로이드로 한번 구현해보았다.


1. activity_main.xml  디자인 구현


좀 작아서 안보이긴 하겠지만 text필드의 E-mail, password필드를 이용해서 구성하고 Button 2개, Large text 2개를 구성해서 저런 화면으로 배치해보았다. 솔직히 모양은 그렇게 크게 맘에 들진 않지만 나중에 뒤에 배경도 같이 한번 넣어볼 계획이다. 


2. activity_main.xml text구현

이젠 텍스트 어떤식으로 배치할 것이며 간격은 얼마나 할건지에 대한 코딩이다. 나는 다음과 같이 코딩했다.

?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.gunjoolee.myapple.MainActivity"
android:gravity="right">

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:ems="10"
android:id="@+id/etEmail"
android:hint="Email"
android:layout_centerVertical="true"
android:layout_alignParentEnd="true" />

<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="Password"
android:ems="10"
android:id="@+id/etPassword"
android:layout_below="@+id/etEmail"
android:layout_alignParentRight="true" />

<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="회원가입"
android:id="@+id/btnRegist"
android:layout_below="@+id/etPassword"
android:layout_centerHorizontal="true" />

<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="로그인"
android:id="@+id/btnLogin"
android:onClick="onButtonClicked"
android:nestedScrollingEnabled="false"
android:layout_alignTop="@+id/btnRegist"
android:layout_alignEnd="@+id/etPassword" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="이메일: "
android:id="@+id/textView"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="비밀번호: "
android:id="@+id/textView2"
android:layout_above="@+id/btnRegist"
android:layout_alignParentStart="true" />

</RelativeLayout>

Linear Layout으로 하려다 그냥 Relative Layout로 했다. 별 내용은 없고 어떤식으로 배치할 것인지에 대해 짠 코드다.


3. Main_activity.java 파일에 대한 구현

방금 만든 화면에 대한 코딩이다. 어떤식으로 동작하게 할지에대한 코딩이다.

package com.example.gunjoolee.myapple;
;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private EditText etEmail;
private Button btnRegist;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

etEmail = (EditText) findViewById(R.id.etEmail);
btnRegist = (Button) findViewById(R.id.btnRegist);
btnRegist.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), RegistActivity.class);

// SINGLE_TOP : 이미 만들어진게 있으면 그걸 쓰고, 없으면 만들어서 써라
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

// 동시에 사용 가능
// intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);

// intent를 보내면서 다음 액티비티로부터 데이터를 받기 위해 식별번호(1000)을 준다.
startActivityForResult(intent, 1000);
}
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

// setResult를 통해 받아온 요청번호, 상태, 데이터
Log.d("RESULT", requestCode + "");
Log.d("RESULT", resultCode + "");
Log.d("RESULT", data + "");

if(requestCode == 1000 && resultCode == RESULT_OK) {
Toast.makeText(MainActivity.this, "회원가입을 완료했습니다!!", Toast.LENGTH_SHORT).show();
etEmail.setText(data.getStringExtra("email"));
}
}

public void onButtonClicked(View v) {

Intent intent = new Intent(getApplicationContext(), finalActivity.class);
startActivity(intent);
finish();
}

}

아 옆에 세어나간게 있는데 양해부탁-_-;; 대강 이런식으로 한번 만들어봤다. onClick를 통해 intent 액티비티가 가능하게 하고 회원가입이 되면 회원가입이 되었다는 문구를 넣음으로써 한번 만들어봤다. 마지막 라인에 있는 코드는 로그인 되었을시 화면전환에 대한 코드를 작성했다. finalActivity라는 파일을 상속시켜서 만들어봤다.


4. Activity_regist.xml 화면 디자인 구성


대강 이런식으로 구성해보았다. 사용했었던 text는 아까하고 똑같은걸 사용했다. 단지 배치만 좀 달라졌을뿐이다. 아무튼 화면은 저렇게 구성을 했고 text에 대한 코드는 다음과 같다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.gunjoolee.myapple.RegistActivity">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:ems="10"
android:hint="Email"
android:id="@+id/etEmail" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="Password"
android:id="@+id/etPassword" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:hint="Password"
android:id="@+id/etPasswordConfirm" />

<LinearLayout
android:orientation="horizontal"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<Button
android:id="@+id/btnDone"
android:text="가입"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<Button
android:id="@+id/btnCancel"
android:text="취소"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>


</LinearLayout>


이런식으로 텍스트 배치를 해보았다. 저 배치가 딱 정석인거같다. 여러모로 테스트해보고 배치 해본 결과이다.


5. Regist.Activity.java 코드

이제 이 화면이 어떻게 동작할지에 대해 코드를 짜보았다. 코드는 다음과 같다.

package com.example.gunjoolee.myapple;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class RegistActivity extends AppCompatActivity {

private EditText etEmail;
private EditText etPassword;
private EditText etPasswordConfirm;
private Button btnDone;
private Button btnCancel;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_regist);

etEmail = (EditText) findViewById(R.id.etEmail);
etPassword = (EditText) findViewById(R.id.etPassword);
etPasswordConfirm = (EditText) findViewById(R.id.etPasswordConfirm);
btnDone = (Button) findViewById(R.id.btnDone);
btnCancel = (Button) findViewById(R.id.btnCancel);

// 비밀번호 일치 검사
etPasswordConfirm.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String password = etPassword.getText().toString();
String confirm = etPasswordConfirm.getText().toString();

if( password.equals(confirm) ) {
etPassword.setBackgroundColor(Color.GREEN);
etPasswordConfirm.setBackgroundColor(Color.GREEN);
} else {
etPassword.setBackgroundColor(Color.RED);
etPasswordConfirm.setBackgroundColor(Color.RED);
}
}

@Override
public void afterTextChanged(Editable s) {

}
});

btnDone.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

// 이메일 입력 확인
if( etEmail.getText().toString().length() == 0 ) {
Toast.makeText(RegistActivity.this, "Email을 입력하세요!", Toast.LENGTH_SHORT).show();
etEmail.requestFocus();
return;
}

// 비밀번호 입력 확인
if( etPassword.getText().toString().length() == 0 ) {
Toast.makeText(RegistActivity.this, "비밀번호를 입력하세요!", Toast.LENGTH_SHORT).show();
etPassword.requestFocus();
return;
}

// 비밀번호 확인 입력 확인
if( etPasswordConfirm.getText().toString().length() == 0 ) {
Toast.makeText(RegistActivity.this, "비밀번호 확인을 입력하세요!", Toast.LENGTH_SHORT).show();
etPasswordConfirm.requestFocus();
return;
}

// 비밀번호 일치 확인
if( !etPassword.getText().toString().equals(etPasswordConfirm.getText().toString()) ) {
Toast.makeText(RegistActivity.this, "비밀번호가 일치하지 않습니다!", Toast.LENGTH_SHORT).show();
etPassword.setText("");
etPasswordConfirm.setText("");
etPassword.requestFocus();
return;
}

Intent result = new Intent();
result.putExtra("email", etEmail.getText().toString());

// 자신을 호출한 Activity로 데이터를 보낸다.
setResult(RESULT_OK, result);
finish();
}
});

btnCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});

}
}

대략 이런식으로 구성해보았다. 비밀번호를 입력하게 되면 서로 일치하지않으면 빨간색, 일치하게 되면 가입이 되게 만들었는데 이건 구글링 해봐서 찾았다. 사실 여기서 내가 짠건 거의 없다...ㅠㅠ 하지만 코드를 보면 뭔지는 이해가 간다. 아무튼 이런식으로 화면구성 프로그램을 짜봤다.


6. Activity_final.xml 구성

이제 로그인 시키면 뭐가 나오는지에 대한 화면 구성이다. 대략적으로 나는 이렇게 만들었다.


매출관리,고객관리,상품관리 이렇게 3개를 만들었다. 그리고 text라인에 가선 이렇게 짜봤다.

?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical"
tools:context="com.example.gunjoolee.myapple.finalActivity">

<Button

android:layout_width="300dp"

android:layout_height="wrap_content"

android:text="고객 관리"

android:id="@+id/button2"

android:layout_gravity="center"

android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="63dp" />


<Button

android:layout_width="300dp"

android:layout_height="wrap_content"

android:text="매출 관리"

android:id="@+id/button3"

android:layout_gravity="center"

android:layout_alignParentTop="true"
android:layout_alignStart="@+id/button2" />


<Button

android:layout_width="300dp"

android:layout_height="wrap_content"

android:text="상품 관리"

android:id="@+id/button4"

android:layout_gravity="center"
android:layout_below="@+id/button3"
android:layout_alignStart="@+id/button3"
android:layout_marginTop="94dp" />

</RelativeLayout>

이렇게 만들어주면 저 위화면하고 똑같이 나온다. 아까 처음에만든 main에서 이미 이 액티피티에 대한걸 클래스로 상속시켜줬기때문에 생략하겠다.


7. Activity_final.java의 대한 코드 구성 

여기선 별거 없다. 다음과 같이 짜여졌다.

package com.example.gunjoolee.myapple;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;








public class finalActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
}
}


자, 이렇게 모두 구성이 완료되었다. 실행시켜보면 다음과 같아진다.




8. 실행화면




반응형
블로그 이미지

만년필석사

,
반응형

이번시간엔 웜바이러스에 대해서 포스팅해보려고한다. 사실 웜바이러스는 현존하는 바이러스 중 정말 무서운 바이러스다. 컴퓨터바이러스 대부분은 자기 자신을 복제하지 못하는데 웜바이러스는 그게 가능하다. 웜바이러스 하나만 퍼뜨려도 무한증식이 가능해서 네트워크 전체로 자기자신을 복제하며 퍼져 나간다는 것이다. 


⊙ 웜바이러스 창시자 모리스 웜

로버트
지금으로부터 26년전 그는 당시 매사츄세츠 공과대학(MIT) 인공지능 연구실에 있던 'VAX서버'에 침투하려고 했다. 자신의 존재가 노출되지 않도록 MIT 내의 PC를 사용했다. MIT 시스템에 침투한 모리스웜은 해당 프로그램을 차단하지 못하도록 막는 기능을 가졌다. 해당 프로그램이 작동되지 못하도록 할 때 마다 7번씩 자신을 복제해 전파되는 구조였다.​ 모리스는 이 웜이 유포되는 것을 통제할 수 있다고 믿었으나 해당 웜이 가진 자체 버그 때문에 썬 OS 시스템 등을 포함해 많은 시스템을 마비시켰다. 그당시 모리스웜은 박사과정중인 대학원생이었다. 이러한 모리스웜의 웜바이러스는 사회적으로도 큰 파장이 일었다. 위에서 말했듯 자기증식이 가능하기 때문에 네트워크나 인터넷으로 퍼지는것이 순식간이었기 때문에 미국의 많은 네트워크와 인터넷을 마비시켰다. 결국 모리스웜은 컴퓨터 보안법위반으로 구속되서 징역 3년형을 살았다. 하지만 지금은  현재 자신이 공격했던 MIT 내 인공지능연구소(CSAIL) 소속 병렬 및 분산 운영체제(PDOS) 그룹 담당 교수로 근무 중이다. 사회적으로 파란이 많았던 사람이지만 아마 바이러스를 만드는 방법을 알기때문에 어떻게 보안을 해야하는지도 잘 알기 때문에 그런 여러가지 공로를 인정받아 지금의 교수가 되지 않았나 생각이든다. 그리고 웜의 또하나의 중요한 특징은 정상파일을 감염시키지는 않는다는 것이다. 웜은 그냥 자신을 복제해서 퍼뜨리는 역할만 한다는 것이다. 웜의 경우는 그냥 삭제만 잘해주면 큰 문제는 없다. 치료프로그램에서 웜이라고 감지된파일을 삭제를 잘해주기만 하면 큰 문제는 없을 것이다.



대표적인 웜

Win32/Blaster.worm 
Win32/IRCBot.worm 
Win32/Bagle.worm

반응형

'보안동향 > 컴퓨터 바이러스 ' 카테고리의 다른 글

트로이목마바이러스  (1) 2016.08.16
블로그 이미지

만년필석사

,
반응형

이번시간엔 리눅스 다운됐을시에 어떻게 해야하는지에 대해 포스팅하려고한다. 본인은 zsh라는 리눅스 파일을 uninstall을 시켜서 리눅스 프로세스정지되고 아무것도 안쳐져서 많이 당황했고 os도 다시 깔아보고 그랬지만 소용이 없었다. 그래서 해결방안은 다음과 같다.


1. 사진은 포스팅 못하지만 터미널을 실행시키면 맨아래에 프로세스정지라고 뜨면서 분명 아무것도 안쳐질 것이다. 그럼 그땐 터미널 환경설정에 들어가서 일반탭에 셀열기쪽으로 가서 명령(절대경로)를 체크표시하고 경로를 /bin/bash로  바꿔준다. 


2. 설정이 되고 다시 터미널을 실행시키면 정상적으로 작동이 될것이다.


3. iterm도 똑같이 실행이 안될 것이다. 터미널을 켜서 chsh –s /usr/local/bin/zsh라고 치면 iterm도 아주 잘 실행될 것이다.


진짜 이거 하다 진땀 뺐다-_-;; zsh파일은 절대로 함부로 삭제하면 안된다!!!

반응형
블로그 이미지

만년필석사

,
반응형

이번시간엔 채팅프로그램에 대해서 포스팅해보려고한다. 사실 채팅프로그램 만드는게 쉽지 않았다. 컴퓨터 환경맞춰야하지, 구글링 해봐야하지. 구글링에서 찾아도 또 리눅스 환경 설치해야하고 정말 어려움이 많았다. 하지만 이걸 만들어봄으로써 node.js에 대해서도 많이 배울 수 있었다. 본 포스팅은 맥북 기준 포스팅이다. 




1. node.js의 설치





일단 node.js를 설치해줘야 한다. 맥북같은 경우는 브루로 금방 깔 수 있을 것이다.


2. express 프레임워크의 설치

npm install --save express를 리눅스에 입력해서 설치한다.


3. 서버 구동 확인

var app = require('express')();

var http = require('http').Server(app);

var io = require('socket.io')(http);


app.get('/', function(req, res){

  res.sendFile(__dirname + '/index.html');

});


http.listen(3000, function(){

  console.log('listening on *:3000');

});


이걸 그대로 Sublime Text에 입력해서 서버가 잘 동작하는지 테스트해본다.  만약에 ^327 에러가 나온다면 express 프레임워크에 var에 관련된 항목들이 설치가 안된것이다. 그땐 npm install http, npm install socket.io를 쳐서 설치해주고 실행해본다. 그러면 아마 서버가 잘 동작할 것이다. 만약 다 됐으면 localhost:3000을 인터넷 주소에다 쳐서 확인해본다. 



이렇게 나오면 정상이다.


4. index.js 파일 만들기

Sublime Text에다 다음과 같은 코드를 입력하고 index.js로 저장해준다.


var app = require('express')();

var http = require('http').Server(app);

var io = require('socket.io')(http);


app.get('/', function(req, res){

  res.sendFile(__dirname + '/index.html');

});


http.listen(5000, function(){

  console.log('listening on *:5000');

});




var userList = [];



io.on('connection', function(socket){

  var joinedUser = false;

  var nickname;


  // 유저 입장

  socket.on('join', function(data){

    if (joinedUser) { // 이미 입장 했다면 중단

      return false; 

    }


    nickname = data;

    userList.push(nickname);

    socket.broadcast.emit('join', { 

      nickname : nickname

      ,userList : userList

    });


    socket.emit('welcome', { 

      nickname : nickname

      ,userList : userList

    });


    joinedUser = true;

  });



  // 메시지 전달(내가 치면 나오는 메시지)

  socket.on('msg', function(data){

    console.log('msg: ' + data);

    io.emit('msg', { 

      nickname : nickname

      ,msg : data

    });

  });



  // 접속 종료

  socket.on('disconnect', function () {

    // 입장하지 않았다면 중단

    if ( !joinedUser) { 

      console.log('--- not joinedUser left'); 

      return false;

    }


    // 접속자목록에서 제거

    var i = userList.indexOf(nickname);

    userList.splice(i,1);


    socket.broadcast.emit('left', { 

      nickname : nickname 

      ,userList : userList

    });    

  });

});


5. index.html이라고 파일명을 저장하고 다음과 같이 코딩한다.


<!doctype html>

<html>

<head>

  <title>Socket.IO chat</title>

  <style>

    * { margin: 0; padding: 0; box-sizing: border-box; }

    body { font: 13px Helvetica, Arial; }

    form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }

    form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }

    form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }

    #messages { list-style-type: none; margin: 0; padding: 0; }

    #messages li { padding: 5px 10px; }

    #messages li:nth-child(odd) { background: #eee; }


    #messages span.nickname { font-weight: bold; font-size: 120%; display: inline-block; width: 100px; }



    div.userList { text-align: center; width: 200px; min-height: 200px; border: 1px solid #999;}

    #userList { list-style-type: none; margin: 0; padding: 0; }

    #userList li { }


    #before { text-align: center; margin-top: 50%; }

    #after { display: none; }

    .noti { text-align: center; color: blue; }

  </style>

</head>

<body>


<section id="before">

  <p>닉네임을 입력하세요</p>

  <input id="nickname"><button id="joinBtn">들어가기</button>

</section>



<section id="after">

  <div class="userList">

    <h2>현재 접속자</h2>

    <ul id="userList"></ul>

  </div>


  <hr>

  <ul id="messages"></ul>

  <form>

    <input id="m" autocomplete="off" /><button>Send</button>

  </form>

</section>


<script src="/socket.io/socket.io.js"></script>

<script src="http://code.jquery.com/jquery-1.11.1.js"></script>

<script>


var nickname;

var socket = io();


// 이벤트: join 클릭 

$('#joinBtn').click(function(e){  

  fnNickname(e);

});


// 이벤트: nickname 엔터키 

$('#nickname').keypress(function(e) { 

  if (e.which == 13) {

    fnNickname(e);

  }

});


// 송신: 닉네임

function fnNickname(e) {

  if ($('#nickname').val().trim() == '') {

    alert('Input your nickname!');

    return false;

  }

  nickname = $('#nickname').val().trim();

  socket.emit('join', nickname);  // 접속 이벤트

}




// 수신: 환영인사

socket.on('welcome', function(data){

  // 유저리스트 업데이트

  fnUpdateUserList(data.userList);


  $('#before').hide();

  $('#after').show();

  $('#messages').append($('<li class="noti">').text(nickname + '님 환영합니다.'));  

});



// 유저리스트 업데이트

function fnUpdateUserList(userList) {

  $('#userList').text('');

  for (i = 0; i < userList.length; i++) {

    $('#userList').append($('<li>').text(userList[i]));

  };

}


// 수신: 신규자 접속

socket.on('join', function(data){

  // 입장 알림

  $('#messages').append($('<li class="noti">').text(data.nickname + '님이 입장하셨습니다'));

  

  // 유저리스트 업데이트

  fnUpdateUserList(data.userList);

});


// 수신: 퇴장

socket.on('left', function(data){

  // 종료 알림

  $('#messages').append($('<li class="noti">').text(data.nickname + '님이 퇴장하셨습니다'));

  

  // 유저리스트 업데이트

  fnUpdateUserList(data.userList);

});



// 송신: 메시지

$('form').submit(function(){

  socket.emit('msg', $('#m').val());

  $('#m').val('');

  return false;

});

  


// 수신: 메시지

socket.on('msg', function(data){

  var span = $('<span class="nickname">').text(data.nickname);

  var li = $('<li>').append(span).append(data.msg);

  $('#messages').append(li);

});


</script>


</body>


6. 서버를 구동시키고 닉네임 달아서 로그인하면 다음과 같이 나올 것이다.


출저: 개발::[Express.js] Node.js


간단해 보이지만 환경구축하고 설치하고 고생많이했다... 다음번에는 귓속말까지 가능한 채팅프로그램을 만들어볼 생각이다. 


반응형

'javascript' 카테고리의 다른 글

casper.js를 이용한 날씨프로그램  (0) 2016.08.30
블로그 이미지

만년필석사

,

DeadLock 특징들

운영체제 2016. 8. 19. 22:29
반응형

이번시간엔 교착상태에 대해서 설명해 보려고한다. 사실 os에서 가장 중요하다고 봐도 과언이 아니다. 학교 시험이나 나중에 대학원 컴퓨터공학과 구술면접때도 교착상태에 대해서 단골로 질문하곤 한다고 한다. 그만큼 중요하니깐 질문하는것이겠지..ㅎㅎ 





1. DeadLock(교착상태)란?

어떤 집합 내에 있는 모든 프로세스가 대기상태이며, 이 집합내에 있는 프로세스가 이 집합내에 다른 프로세스가 가지고 있는 자원을 기다리고 있는 현상을 교착상태라고 한다. 한마디로 이야기해서  두개이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있고 아무런 작업도 하지 못한채 계속 무한정 대기하는 상태이다. 



사진출저: google



2. 교착상태가 일어나기 위한 조건


① 상호배제: 프로세스들이 필요로하는 자원에 대해 배타적인 통제권을 요구한다.

② 점유대기: 프로세스가 할당한 자원을 가진 상태에서 다른자원을 기다린다.

③ 비선점: 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.

순환대기; 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.


--> 이 조건을 모두 만족해야 교착상태가 일어난다. 


3. 교착상태의 예방조건


  • 상호배제 조건의 제거
교착 상태는 두 개 이상의 프로세스가 공유 불가능한 자원을 사용하니 발생하는 것이므로 공유 불가능한, 즉사 상호 배제 조건을 제거하면 교착 상태를 해결할 수 있다.

  • 점유와 대기 조건의 제거
한 프로세스에 수행되기 전에 모든 자원을 할당시키고 나서 점유하지 않을 때에는 다른 프로세스가 자원을 요구하도록 하는 방법이다. 자원 과다 사용으로 인한 효율성, 프로세스가 요구하는 자원을 파악하는 데에 대한 비용, 자원에 대한 내용을 저장 및 복원하기 위한 비용, 기아상태, 무한 대기 등의 문제점이 있다.

  • 비선점 조건의 제거
 비선점 프로세스에 대해 선점 가능한 프로토콜을 만들어 준다.

  • 환형 대기 조건의 제거
 자원 유형에 따라 순서를 매긴다.

이 교착 상태의 해결 방법들은 자원 사용의 효율성이 떨어지고 비용이 많이 드는 문제점이 있다.

출저: Lael's World

4. 교착상태 회피

-> 교착상태 발생시 피해나가는 방법. 은행원 알고리즘이 가장 대표적이다.

※ 은행원 알고리즘

E,J,Dijkstra가 제안한 방법으로, 은행에서 모든 고객의 요구가 충족되도록 현금을 할당하는 데서 유래한 기법이다

프로세스가 자원을 요구할 때 시스템은 자원을 할당한 후에도 상태로 남아있게 되는지를 사전에 검사하여 교착 상태를 회피하는 기법

안정 상태에 있으면 자원을 할당하그렇지 않으면 다른 프로세스들이 자원을 해지할 때까지 대기함


출저: #include <stdio.h>


5. 교착상태 회복법??

- 교착상태를 일으킨 프로세스를 종료하거나, 할당된 자원을 해제함으로써 회복하는 것을 말한다.

- 프로세스 종료법

1. 교착상태의 프로세스를 모두 중지

2. 교착상태가 제거될 때까지 한 프로세스씩 중지

- 자원선점법

1. 교착상태의 프로세스가 점유하고 있는 자원을 선점해 다른프로세스에게 할당하며, 해당프로세스를 일으킬 시 정지시키는 방법

2. 우선순위가 낮은 프로세스등을 위주로 프로세스의 자원을 선점한다.

출저: #include <stdio.h>



반응형

'운영체제 ' 카테고리의 다른 글

이중동작모드(Dual-Mode operation)  (0) 2017.01.15
멀티프로세싱(Multi Processing)이란?  (0) 2016.09.20
임계구역(Critical section)  (0) 2016.09.11
Context Switching  (0) 2016.09.08
가상메모리  (0) 2016.08.10
블로그 이미지

만년필석사

,
반응형

원하는 포맷의 파일의 갯수를 확인하는 방법이다. 유용하긴한데 외워서 딱 쓰기엔 시간이 많이 걸려보인다. 많이 써봐야 잘 쓸수 있을듯한 명령어다.

  find. name '*.extention ' | wc -1


반응형
블로그 이미지

만년필석사

,
반응형

아래의 명령어는 Javascript 포맷만 code line을 카운팅 한다.


find . -name '*.js' | xargs wc -l


이건 그냥.. 포스팅해놓고 그때그때 유용하게 쓰는게 좋은거같다. 계속 써봐야 외워지는 명령어같다. 


반응형
블로그 이미지

만년필석사

,