메뉴 건너뛰기

조회 수 11722 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

안드로이드 소켓 프로그래밍 테스트를 위해 간단한 채팅프로그램을 만들어 봤습니다.

 

클라이언트는 자바를 이용해 만들었고 서버는 C#을 이용해 만들었습니다.

 



 

 

 

 

- 클라이언트 -

 

main.xml

-------------------------------------------------------------------------------------------

<?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"
    >
    <LinearLayout
     android:layout_height="wrap_content" 
     android:layout_width="fill_parent">
        <TextView
         android:text="닉네임"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">
        </TextView>
        <EditText
         android:text="Guest"
         android:id="@+id/connText"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_weight="1">
        </EditText>
        <Button
         android:text=" 접속 "
         android:id="@+id/connBtn"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="connBtnClick">
        </Button>
        <Button
         android:text=" 종료 "
         android:id="@+id/closeBtn"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:onClick="connBtnClick">
        </Button>
    </LinearLayout>
    <ScrollView
     android:id="@+id/scrollView1"
     android:layout_height="wrap_content"
     android:layout_width="fill_parent"
     android:layout_weight="1"
     android:fillViewport="true"
     >
        <LinearLayout
         android:layout_width="fill_parent"
         android:layout_height="fill_parent">
         <TextView 
       android:layout_width="fill_parent"
       android:id="@+id/text01"
       android:singleLine="false"
       android:layout_height="wrap_content"
     />
        </LinearLayout>
    </ScrollView> 
 <LinearLayout
  android:layout_height="wrap_content"
  android:layout_width="fill_parent"
  android:gravity="bottom">
  <EditText
   android:id="@+id/chatText"
   android:text=""
   android:layout_height="wrap_content"
   android:layout_width="wrap_content"
   android:layout_weight="1"
   >
  </EditText>
  <Button
   android:text="보내기"
   android:id="@+id/sendBtn"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:onClick="connBtnClick">
  </Button>
 </LinearLayout> 
</LinearLayout>

-------------------------------------------------------------------------------------------

 

andChatSample.java

-------------------------------------------------------------------------------------------

package exam.andChatSample;

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

import android.app.*;
import android.os.*;
import android.view.*;
import android.widget.*;

public class andChatSample extends Activity {
    /** Called when the activity is first created. */
 public Socket cSocket = null;
 private String server = "123.123.123.123";  // 서버 ip주소
 private int port = 9000;                           // 포트번호
 
 public PrintWriter streamOut = null;
 public BufferedReader streamIn = null;
 
 public chatThread cThread = null;
 
 public TextView tv;
 public EditText nickText;
 public EditText msgText;
 public ScrollView sv;
 
 public String nickName;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        sv = (ScrollView)findViewById(R.id.scrollView1);
        tv = (TextView)findViewById(R.id.text01);
        nickText = (EditText)findViewById(R.id.connText);
        msgText = (EditText)findViewById(R.id.chatText);
       
        logger("채팅을 시작합니다.");
    }
   
    public void onDestroy() { // 앱이 소멸되면
     super.onDestroy();
     if (cSocket != null) {
    sendMessage("# [" + nickName + "]님이 나가셨습니다.");
  }
    }
   
    public void connBtnClick(View v) {
     switch (v.getId()) {
     case R.id.connBtn: // 접속버튼
      if (cSocket == null) {
          nickName = nickText.getText().toString();
          logger("접속중입니다...");
          connect(server, port , nickName);
         }
      break;
     case R.id.closeBtn: // 나가기 버튼
      if (cSocket != null) {
       sendMessage("# [" + nickName + "]님이 나가셨습니다.");
      }
     break;
     case R.id.sendBtn: // 메세지 보내기 버튼
      if (cSocket != null) {
       String msgString = msgText.getText().toString();
          if (msgString != null && !"".equals(msgString)) {
              sendMessage("[" + nickName + "] " + msgString);
              msgText.setText("");
             }
      } else {
       logger("접속을 먼저 해주세요.");
      }      
     break;      
     }
    }

   
    public void connect(String server, int port, String user) {
  try {
   cSocket = new Socket(server, port);
   streamOut = new PrintWriter(cSocket.getOutputStream(), true);      // 출력용 스트림
   streamIn = new BufferedReader(new InputStreamReader(cSocket.getInputStream()));  // 입력용 스트림
   
   sendMessage("# 새로운 이용자[" + user + "]님이 들어왔습니다.");
   
   cThread = new chatThread();
   cThread.start();
  }catch (Exception ex) {
   logger("접속이 제대로 이루어 지지 않았습니다.");
  }
 }
   
    private void logger(String MSG) {
     tv.append(MSG + "\n");     // 텍스트뷰에 메세지를 더해줍니다.
     sv.fullScroll(ScrollView.FOCUS_DOWN); // 스크롤뷰의 스크롤을 내려줍니다.
    }
   
    private void sendMessage(String MSG) {
     try {
      streamOut.println(MSG);     // 서버에 메세지를 보내줍니다.
     } catch (Exception ex) {
      logger(ex.toString());
     }
  
 }
   
    Handler mHandler = new Handler() {   // 스레드에서 메세지를 받을 핸들러.
     public void handleMessage(Message msg) {
      switch (msg.what) {
      case 0: // 채팅 메세지를 받아온다.
       logger(msg.obj.toString());
       break;
      case 1: // 소켓접속을 끊는다.
       try {       
        cSocket.close();
        cSocket = null;
        
        logger("접속이 끊어졌습니다.");
        
       } catch (Exception e) {
        logger("접속이 이미 끊겨 있습니다." + e.getMessage());
        finish();
       }
       break;
      }
     }
    };
   
    class chatThread extends Thread {
     private boolean flag = false; // 스레드 유지(종료)용 플래그

     public void run() {
      try {
       while (!flag) { // 플래그가 false일경우에 루프
        String msgs;
        Message msg = new Message();
           msg.what = 0;
           msgs = streamIn.readLine();  // 서버에서 올 메세지를 기다린다. 
           msg.obj = msgs;
           
           mHandler.sendMessage(msg); // 핸들러로 메세지 전송
           
           if (msgs.equals("# [" + nickName + "]님이 나가셨습니다.")) { // 서버에서 온 메세지가 종료 메세지라면
            flag = true;   // 스레드 종료를 위해 플래그를 true로 바꿈.
            msg = new Message();
            msg.what = 1;   // 종료메세지
            mHandler.sendMessage(msg);
           }               
          }
       
      }catch(Exception e) {
       logger(e.getMessage());
      }
     }     
    }
}

-------------------------------------------------------------------------------------------

 

- 서버 -

 

program.cs

-------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace chatServerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            BroadcastServer.start(10701);
        }
    }
}

-------------------------------------------------------------------------------------------

 

BroadcastServer.cs

-------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;

namespace chatServerTest
{
    class BroadcastServer
    {
        public static ArrayList socketList = new ArrayList(); //서버에 연결된 소켓들의 Array 입니다.
        private static BroadcastServer broadcastServer;
        private Thread threadWaitingSocket;
        private Socket listener;       
        private int port;

        public static void start(int _port) //   서버 시작
        {
            if (broadcastServer == null)
            {
                broadcastServer = new BroadcastServer(_port);
            }
        }

        public static void stop()       // 서버 종료
        {
            Console.WriteLine("서버를 종료합니다.");
            foreach (SocketHandler socketHandler in socketList)
            {
                socketHandler.end();
            }
            if (broadcastServer != null)
            {
                broadcastServer.threadStop();
            }
        }

        private void threadStop()
        {
            threadWaitingSocket.Abort();
            listener.Close();
        }

        private BroadcastServer(int _port)
        {
            port = _port;
            threadWaitingSocket = new Thread(new ThreadStart(WaitingSocket));
            threadWaitingSocket.Start();
        }

        private void WaitingSocket()    //  클라이언트의 접속을 체크하는 스레드.
        {
            IPAddress ipAddress = IPAddress.Any;

            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            listener.Bind(ipEndPoint);
            listener.Listen(1000);      //  동시에 접속할 접속자수를 설정

            Console.WriteLine("연결을 기다립니다.");

            while (true)
            {
                Socket acceptedSocket = listener.Accept();      //  접속한 클라이언트 소켓

                string acceptedIP = ((IPEndPoint)acceptedSocket.RemoteEndPoint).Address.ToString(); //  접속한 클라이언트 IP

                socketList.Add(new SocketHandler(acceptedSocket));                                  //  접속리스트에 추가

                Console.WriteLine(socketList.Count + "번째 컴퓨터 - " + acceptedIP + "에서 접속하였습니다.");
            }

        }
    }

    public class SocketHandler
    {
        public Socket socket;
        public Thread threadHandler;

        public SocketHandler(Socket socket)
        {
            this.socket = socket;
            threadHandler = new Thread(new ThreadStart(Handler));
            threadHandler.Start();           
        }

        public void Handler()                   //  실질적인 서버작업
        {
            byte[] buffer = new byte[4096];
            int bufferCount;

            SendMsg((BroadcastServer.socketList.Count) + "명이 접속해 있습니다.");

            try
            {
                while (true)
                {
                    buffer.Initialize();
                    bufferCount = socket.Receive(buffer);

                    if (bufferCount == 0) break;

                    string Msgs = ASCIIEncoding.UTF8.GetString(buffer);

                    byte[] byteimsi = new byte[bufferCount];    // 남은버퍼 없애기용 임시byte
                    for (int i = 0; i < bufferCount; i++)
                    {
                        byteimsi[i] = buffer[i];
                    }
                    Msgs = ASCIIEncoding.UTF8.GetString(byteimsi);
                    Console.WriteLine("클라이언트에서 받은 메세지" + Msgs);

                    SendMsg(Msgs);

                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            finally
            {
                Console.WriteLine("클라이언트가 종료하였습니다.");

                BroadcastServer.socketList.Remove(this);
                socket.Close();
                socket = null;
            }
        }

        public void SendMsg(string Msg)     //  메세지 보내기.
        {
            int bufferCount = 0;

            byte[] buffer = new byte[4096];

            buffer = ASCIIEncoding.UTF8.GetBytes(Msg);
            bufferCount = ASCIIEncoding.UTF8.GetByteCount(Msg);

            foreach (SocketHandler socketHandler in BroadcastServer.socketList)
            {
                socketHandler.socket.Send(buffer, 0, bufferCount, SocketFlags.None);
            }
        }

        public void end()
        {
            threadHandler.Abort();
        }
    }
}
-------------------------------------------------------------------------------------------

 


List of Articles
번호 제목 날짜 조회 수
237 HTML5로 나만의 비디오 플레이어 스킨 만들기 -2- JavaScript file 2014.09.04 6312
236 HTML5로 나만의 비디오 플레이어 스킨 만들기 -3- JavaScript file 2014.09.04 6288
235 HTML5 드래그 앤 드롭 하기 Drag and Drop file 2014.09.04 7748
234 HTML5 Web Storage -01- file 2014.09.04 5587
233 HTML5 Form 공부하기 -1- file 2014.09.04 5841
232 HTML5 Form 공부하기 -2- file 2014.09.04 6329
231 HTML5로 게임 만들기 워밍업 file 2014.09.04 6063
230 HTML5 Better semantic tags file 2014.09.04 5952
229 HTML5 Geolocation (구글 지도에 현위치 표시하기) file 2014.09.04 6810
228 jQuery ajax post 요청 text 응답 2014.10.16 6702
227 JSON(JavaScript Object Notation) - jQuery Ajax - jQuery.getJSON() 메서드 (비동기적으로 JSON파일 로드) file 2014.10.16 6568
226 jQuery Ajax - jQuery.load() 메서드 (동적으로 원격 페이지 로드) file 2014.10.16 6409
225 트리뷰(TreeView) 컨트롤 file 2014.10.16 6720
224 Effects - Stop() 메서드 (애니메이션 효과 멈추기) file 2014.10.16 6225
223 Effects - Animate() 메서드 (여러가지 효과 동시 처리) file 2014.10.16 30621
222 Effects - SlideToggle() 메서드 (슬라이드 업/다운) file 2014.10.16 6758
221 Effects - SlideUp() 메서드 (슬라이드업) file 2014.10.16 5999
220 Effects - FadeIn() / FadeOut() 메서드 (서서히 보이기 및 숨기기) file 2014.10.16 6069
219 Effects - Show() / Hide() 메서드 (보이기 및 숨기기) file 2014.10.16 5957
218 Events - Unbind() 메서드 (이벤트 처리기 해제) file 2014.10.16 5749
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved