메뉴 건너뛰기

조회 수 11725 추천 수 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 안드로이드 php 로 mysql json 파싱 하기 2014.08.28 9407
256 FTPClient 를이용하여 ftp상 서버에서 데이터 다운로드 편 2014.08.28 9853
255 XmlPullParser 를이용하여 데이터 가져와보기!! 2014.08.28 7221
254 FTPClient 를이용한 데이터 업로드 하기 2014.08.28 6366
253 클래스나눠서 xml 파싱과 FTP를이용하여 안드로이드에서 활용하기 2014.08.28 6180
252 전화 인텐트와 나의 전화 번호가져오기 2014.08.28 6312
251 사진찍기 및 앨범 에서 사진 가져오기!!! 2014.08.28 13889
250 안드로이드 웹에서 이미지 불러오기!! 2014.08.28 7053
249 맵에 오버레이 추가하여 아이템 넣어보기 2014.08.28 6474
248 실행중인 Service 확인하기 2014.08.28 6595
247 안드로이드 이미지 효율적으로 회전 해보기 2014.08.28 5995
246 WIFI 신호세기 강도 측정하기 2014.08.28 11243
245 WebView 줌 컨트롤러 가리기 2014.08.28 6316
244 ImageVeiw의 현재 리소스 비교하기 2014.08.28 6750
243 HTML5 Speech Input (음성인식) API 2014.09.04 6454
242 HTML5 시작하기 file 2014.09.04 5660
241 CSS3 Rounded Corner, 그림자 효과 사용하기 file 2014.09.04 6760
240 JavaScript 맛보기 file 2014.09.04 6589
239 HTML5로 비디오 보여주기 Video Tag file 2014.09.04 7061
238 HTML5로 나만의 비디오 플레이어 스킨 만들기 -1- CSS file 2014.09.04 6453
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved