PDA에서 서버와의 통신을 위해 C# 으로 소켓프로그래밍을 하게 되었는데
소켓프로그래밍 중에서 TCP/IP와 스트림 소켓프로그래밍쪽을 알아보도록 하겠습니다.
먼저 C#에서 소켓프로그래밍을 하기 위해서는
.NET 프래임워크 클래스 라이브러리의
System.net 과 System.Net.Socket 을 사용해야합니다.
using System.Net
using System.Net.Socket
클라이언트 에서 서버로의 접속을 위한 소켓프로그래밍
펼쳐두기..
클라이언트에서 소켓으로 접속하기 위해서는
Socket socket; 으로 소켓 변수를 선언하고
IPAddress 변수명 = IPAddress.Parse("서버의 아이피");
위와 같이 IPAddress 를 선언과 동시 정의합니다.
그리고 Int형 변수로 서버의 포트를 적어주어야 합니다
int serverPort = 서버의 포트번호;
이제 소켓을 정의 해보도록 하겠습니다
socket =
new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
위에서 AddressFamily.InterNetwork 는 IPv4를 사용하겠다는 의미를 가지고 있고
SocketType.Stearm 은 Stream 형식을 사용하겠다고 정의하고 있습니다.
또 ProtocolType.Tcp 는 통신 프로토콜 중에서 TCP/IP 방식을 사용하겠다는 의미입니다.
그리고나서
IPEndPoint ipep = new IPEndPoint(serverIP, serverPort);
네트워크의 끝점을 IP와 포트로 나타내는 것인데 자바에서는 없는 부분이어서
따로 조사해 봤습니다.
IPEndPoint 클래스에는 응용 프로그램에서 호스트 서비스에 연결하는 데 필요한 호스트 정보와 원격 포트 정보가 포함되어 있습니다. IPEndPoint 클래스는 호스트의 IP 주소와 서비스의 포트 번호를 결합하여 서비스에 대한 연결 지점을 형성합니다. (출처 MSDN)
.NET 에서 소켓프로그래밍을 할때 항상 들어가는 구문이네요
다음으로 원격 호스트에 대한 연결을 설정합니다.
socket.Connect(new IPEndPoint(serverIP, serverPort));
위 까지 해서 클라이언트에서 서버로 접속이 이루어 지게 됩니다.
이 코드를 제가 한 코드로 나열하면
소켓역할을 담당할 클래스 안에 Connect() 라는 메소드에 구현하였습니다.
public Socket socket;
public void Connect()
{
try
{
IPAddress serverIP = IPAddress.Parse("서버아이피");
int serverPort = 서버포트;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipep = new IPEndPoint(serverIP, serverPort);
socket.Connect(new IPEndPoint(serverIP, serverPort));
}
catch (SocketException ex)
{
//MessageBox.Show(ex.Message.ToString());
}
}
위와같이 선언 해놓고
서버로 접속을 해서 무언가 해야 할 일이 생기면
Connect() 메소드를 이용하여 접속을 해서 작업하도록 구현했습니다.
서버에서 클라이언트의 접속을 기다리는 부분
펼쳐두기..
서버역시
열어둘 자신의 포트를 정의해야 합니다
private const int ServerPort = 48880;
그리고 소켓변수를 생성합니다.
Socket listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
이 부분은 클라이언트와 동일합니다.
그리고 IPEndPoint 를 선언하는데 이부분은 클라이언트와 조금 다릅니다.
IPEndPoint listenEP = new IPEndPoint(IPAddress.Any, ServerPort);
Any 이부분은 클라이언트 모두의 접속을 받아들여야 하기 때문에 Any를 사용합니다.
그리고 소켓을 연결합니다.
listenSocket.Bind(listenEP);
이 Bind 는 아래의 listen 메소드를 사용하기 위해 선언합니다(참고 MSDN)
listenSocket.Listen(5);
위의 Listen 메소드로 클라이언트의 접속을 기다리게 되며 5라는 것은
동시에 접속가능한 클라이언트의 수를 나타냅니다.
자바의 경우에는 따로 선언하는것이 없이 여러 클라이언트가 접속될 경우 하나하나의
클라이언트접속을 쓰래드로 만들어서 했었는데 조금 생소하네요 ^^;
clientSocket = listenSocket.Accept();
이제 위의 코드가 클라이언트의 접속을 얻어오는 부분입니다.
서버가 위 코드까지 선언되어 있는 상태에서 클라이언트가 접속할 경우
접속이 이루어 지게 됩니다.
데이터를 주고 받게되는 Stream
펼쳐두기..
Stream 에서 는 보내는 부분과 받는 부분으로 나뉘게 되는데
먼저 보내는 부분부터 알아보도록 하겠습니다.
NetworkStream stream = new NetworkStream(socket);
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(req);
writer.Flush();
이름이 약간 틀리긴 하지만 자바와 비슷한 느낌이네요
NetworkStream 과 StreamWriter 를 사용해서
WriteLine 메소드로 한줄을 읽어 들여서
Flush 메소드를 사용해서 보내도록 되어 있습니다.
제 경우에는 저 부분은 하나의 메소드로 사용해서
보낼 문자를 인수로 받아서 보낼때마다 메소드를 호출해서 사용하도록 구현했습니다.
public void request(string req)
{
try
{
String requestServer = req;
NetworkStream stream = new NetworkStream(socket);
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine(req);
writer.Flush();
}
catch (SocketException ex)
{
//MessageBox.Show(ex.Message.ToString());
}
}
필요할 때마다 request("내용"); 이런식으로 사용하면 되겠죠 ^^:
이번에는 받는 부분 입니다.
NetworkStream stream = new NetworkStream(socket);
StreamReader reader = new StreamReader(stream);
string readBuf = reader.ReadLine();
return readBuf;
전송때을 할 때와 비슷하게 NetWorkStream 을 사용하지만
이번에는 읽어 들이기 때문에 StreamReader 를 사용하는 군요
readBuf 라는 string 형 변수를 사용해서 ReadLine() 메소드로 한줄을 읽어 들이고
저장한 readBuf 를 리턴 하는 형식으로 사용하였습니다.
보내는 부분과 마찬가지로 하나의 메소드로 만들어서 필요할 때마다 사용하고있습니다.
public string receive()
{
NetworkStream stream = new NetworkStream(socket);
StreamReader reader = new StreamReader(stream);
string readBuf = reader.ReadLine();
return readBuf;
}
위와 같이 선언해 두고 필요할 때마다 receive 메소드를 호출해서 전송되는 데이터를
받을수 있습니다.(예외처리가 빠져있네요 ^^;)
여기까지 제가 C# 소켓 프로그래밍을 공부한 내용들인데 아직 미숙한면이 많습니다.
조금 이상한 점이라던가 틀린점, 보완할 점들을 댓글로 달아주시면 정말 감사하겠습니다 ^^;
1. C# 소켓 프로그래밍
2. C# 데이터베이스(MS SQL2005 사용)
3. C# 비주얼 프로그래밍 + 이벤트 처리
4. PDA와 연동(액티브 싱크, 윈도우 모바일)
2번의 데이터베이스 연동과 서버의 내용은 같이 만들었던 친구가 했던 부분인데
이 부분들은 친구의 블로그를 링크하도록 하겠습니다.
으음~ 네트워크쪽 보려했는데 많은 참고가 되었습니다. 감사합니다.
답글삭제