메뉴 건너뛰기

조회 수 11723 추천 수 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
번호 제목 날짜 조회 수
257 Activity Data Transfor/ 액티비티 이동간에 데이터 전송하기 file 2016.06.07 7676
256 Activity Switching / 안드로이드 액티비티 전환 / 화면 전환 file 2016.06.07 8311
255 Android Login and Registration with PHP, MySQL and SQLite file 2015.07.16 14178
254 Android Navigation Drawer API 공개! 디자인 가이드 살펴보기 file 2015.07.29 8141
253 Android Push GCM 서버 구성 하기(3) file 2015.12.14 6388
252 Android Push GCM 프로젝트 앱 적용 하기(2) file 2016.03.18 8953
251 android SMS 리시버 2015.06.29 6871
250 Android Studio에서 SQLCipher 라이브러리 추가 방법 file 2018.10.02 1776
249 Android TIP] strings.xml 에서 특수문자 사용하기 2015.12.15 6629
248 Android 간단한 회원 가입 폼 만들기 for Mac (PHPMyAdmin 이용) file 2015.07.10 10508
247 Android 와 JSP 간 파라미터 암복호화 (1) file 2016.05.26 7474
246 Android 와 JSP 간 파라미터 암복호화 (2) 2016.05.26 7735
245 Android 와 JSP 간 파라미터 암복호화 (3) file 2016.05.26 8088
244 android.support.v4.content.FileProvider not found file 2020.12.14 308
243 AndroidManifest에 선언한 메타데이터(meta-data) 가져오기 2016.06.10 9313
242 Android] Fragment 내부의adapter에서 startActivity 하기 2015.12.15 6487
241 Android] 안드로이드 홈 디렉토리 알아내기 2015.12.15 6895
240 Apk manager 이용해 Decompile (디컴파일) 하기 file 2021.03.16 1620
239 App 실행 file 2021.03.31 244
238 CSS3 Rounded Corner, 그림자 효과 사용하기 file 2014.09.04 6760
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved