메뉴 건너뛰기

조회 수 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 카카오톡 분석하기 (1) - sqlite 파해치기 file 2016.05.26 10063
236 카카오톡 대화내용 가져오기(sqlite3, chat_logs) file 2016.05.26 15116
235 초기화면 페이지를 만들어보자. splash 페이지 제작 file 2020.12.14 285
234 체크 박스(CheckBox)의 이미지 바꾸기 2015.07.16 6398
233 줄바꿈 문자 치환 2020.12.14 289
232 전화 인텐트와 나의 전화 번호가져오기 2014.08.28 6312
231 인텐트를 이용한 Activity간 데이터 전달 (사용자 정의 클래스) file 2015.07.16 7061
230 이미지의 Orientation를 체크해서 이미지 회전하기 2015.07.16 7658
229 이미지 버튼(ImageButton) 만들기 2015.07.16 7114
228 이미지 버튼 설정 2015.07.16 6378
227 위젯 업데이트 주기 빠르게 하기 2018.10.02 2142
226 월별 캘린더에 일정 입력 및 조회 기능 리스트로 추가하기 file 2015.07.16 18552
225 옵션 메뉴 동적으로 생성하기 2015.07.16 6926
224 어댑터 뷰(Adapter View) & 어댑터(Adapter) (1) file 2016.06.08 7852
223 앱 번들(Android App Bundle) 만들기 file 2021.09.14 305
222 암시적 인텐트를 사용한 인터넷열기, 전화걸기, 문자보내기 [Intent (인텐트)] file 2016.06.07 7736
221 알아놓으면 좋은 내용정리 2016.06.07 7458
220 안드로이트 비콘 스캐닝시 고려 사항 2015.07.26 6658
» 안드로이드용 채팅프로그램 클라이언트(java), 서버(c#) 소스 file 2016.05.19 11722
218 안드로이드와 mysql 연동시키기. php 와 json 사용 file 2015.07.16 24487
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved