메뉴 건너뛰기

조회 수 7599 추천 수 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
번호 제목 날짜 조회 수
144 카카오톡 분석하기 (1) - sqlite 파해치기 file 2016.05.26 5664
» 안드로이드용 채팅프로그램 클라이언트(java), 서버(c#) 소스 file 2016.05.19 7599
142 네트워크 연결 상태 및 3G/WIFI 연결상태 체크하기 2016.03.18 4913
141 Android Push GCM 프로젝트 앱 적용 하기(2) file 2016.03.18 6055
140 안드로이드] 페이스북 같은 슬라이드 메뉴 만들기 file 2015.12.15 6522
139 Android TIP] strings.xml 에서 특수문자 사용하기 2015.12.15 4265
138 Android] Fragment 내부의adapter에서 startActivity 하기 2015.12.15 4141
137 Android] 안드로이드 홈 디렉토리 알아내기 2015.12.15 4491
136 안드로이드 로그인유지 코드 2015.12.14 5593
135 Android Push GCM 서버 구성 하기(3) file 2015.12.14 4055
134 안드로이드 EditText 필터링 검색 file 2015.12.14 4661
133 안드로이드 EditText 필터링 검색 구현(adapter.getFilter().filter(cs)) file 2015.12.14 5179
132 JAVA JDBC를 사용하여 MySQL과 연동 file 2015.11.20 4822
131 안드로이드 로그인 화면 만들기 file 2015.09.04 5168
130 [안드로이드] 리스트 뷰의 한 항목에 대한 컨텍스트 메뉴 만들기 file 2015.09.03 5182
129 [안드로이드] 빠르게 사용할수 있는 컨텍스트 메뉴 만들기 file 2015.09.03 4007
128 [안드로이드] 팝업메뉴 사용법 file 2015.09.03 5413
127 [안드로이드] 콘텍스트 메뉴 사용예제 file 2015.09.02 4439
126 안드로이드 기본어플 예제 어플소스 모음 2015.08.17 5894
125 [안드로이드 강좌] 초보자들이 많이 하는 실수 file 2015.08.10 4241
Board Pagination Prev 1 2 3 4 5 6 7 8 9 Next
/ 9

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved