嗨,我想尝试制作Messenger
问题描述:
嗨
我的教授给我一个考试项目
做个使者
i`m试图制作一个,但它对我来说太难了
使用套接字服务器和
如果我发送消息然后另一方获得弹出消息
http://image.kilho.net/?pk=1211118 [ ^ ]
服务器
Hi
my professor give me a project for exam
make a messenger
i`m trying to make one, but it`s so difficult to me
use socket server and
if i send message then other side get popup message
http://image.kilho.net/?pk=1211118[^]
Server
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using Pop;
namespace TCP_Server
{
public partial class Form1 : Form
{
//전역 변수 선언부
TcpListener _tcpLitener;
bool _open_flag = false;
Thread _thread_listener;
Thread _thread_receive;
NetworkStream _ntstream;
StreamReader _streader;
StreamWriter _stwriter;
TcpClient _client;
public Form1()
{
InitializeComponent();
}
private void bt_open_Click(object sender, EventArgs e) //서버 오픈 버튼
{
try
{
if (!_open_flag) //현재 접속중인지 아닌지 판단.(첫 접속일 경우 전역변수 선언부에서 false로 선언하였기때문에 접속중이 아님)
{
_tcpLitener = new TcpListener(IPAddress.Parse(tb_ip.Text), int.Parse(tb_port.Text));//텍스트 박스 값으로 TcpListener 생성 (int.parse 는 텍스트를 숫자화 하는 메서드)
_tcpLitener.Start(); //TcpListener 시작
_open_flag = true; //서버를 오픈하였기 때문에 오픈 플래그를 True로 변경
_thread_listener = new Thread(listener); //listener메서드 스레드로 생성
_thread_listener.Start(); //스레드 시작
MessageBox.Show("server start");
}
}
catch (Exception ex) //에러
{
_open_flag = false; //실패할경우 오픈이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString()); //오류 보고
}
} void listener() //접속 Client를 받아들이는 메소드
{
try
{
if (_open_flag) //현재 오픈중인지 아닌지 판단
{
_client = _tcpLitener.AcceptTcpClient(); //Client가 접속할경우 Client변수 생성
MessageBox.Show("Client가 접속하였습니다");
create_stream(); //접속한 Client로 create_stream메소드 실행
}
else
{
MessageBox.Show("서버가 열리지 않았습니다");
}
}
catch(Exception ex) //에러
{
_open_flag = false; //실패할경우 오픈이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString());
}
}
void create_stream()
{
try
{
_ntstream = _client.GetStream(); //접속한 Client에서 networkstream 추출
_client.ReceiveTimeout = 500; //Client의 ReceiveTimeout
_streader = new StreamReader(_ntstream); //추출한 networkstream으로 streamreader,writer 생성
_stwriter = new StreamWriter(_ntstream);
_thread_receive = new Thread(receive); //receive메서드 스레드로 생성
_thread_receive.Start(); //스레드 시작
}
catch (Exception ex) //에러
{
_open_flag = false; //실패할경우 접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString());
}
}
void receive()
{
try
{
while (_open_flag) //현재 오픈중인지 아닌지 판단
{
string _receive_data = _streader.ReadLine(); //streamreader의 한줄을 읽어들여 string 변수에 저장
if (_receive_data != null) //데이터가 null이 아니면
{
Form2 fm2 = new Form2(_client);
fm2.ShowDialog();
}
}
}
catch (IOException) //IO에러 (Timeout에러도 이쪽으로 걸림)
{
if (_open_flag) //현재 접속중인지 아닌지 체크
{
_thread_receive = new Thread(receive); //접속중일 경우 receive메서드를 이용한 스레드 다시생성
_thread_receive.Start();
} //접속중이 아닐경우 자연스럽게 스레드 정지
}
catch (Exception ex) //그 밖의 에러
{
_open_flag = false;
MessageBox.Show("클라이언트의 연결이 종료되었습니다\r\n다시 서버오픈을 시도합니다.");
_tcpLitener.Stop();
bt_open_Click(null, null);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) //FormClosing 이벤트
{
_open_flag = false; //접속중인지 체크하는 _connect_flag를 false로 변경
}
}
}
Form2
Form2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using Pop;
namespace Pop
{
public partial class Form2 : Form
{
NetworkStream _ntstream;
StreamReader _streader;
StreamWriter _stwriter;
Thread _thread_receive;
TcpClient _client;
bool _connect_flag = false;
delegate void D_receive(string data); //델리게이트 다음번에 자세히 설명하겠음.
public Form2(TcpClient client)
{
//_client = client;
MessageBox.Show(Convert.ToString(client));
_client = client;
InitializeComponent();
}
private void tb_connect_Click(object sender, EventArgs e)
{
try
{
if (!_connect_flag) //현재 접속중인지 아닌지 판단.(첫 접속일 경우 전역변수 선언부에서 false로 선언하였기때문에 접속중이 아님)
{
_client = new TcpClient(tb_ip.Text, int.Parse(tb_port.Text));//텍스트 박스 값으로 TcpClient 생성 (int.parse 는 텍스트를 숫자화 하는 메서드)
_connect_flag = true; //접속하였기 때문에 접속 플래그를 True로 변경
_ntstream = _client.GetStream(); //접속한 Cilent에서 networkstream을 추출
_streader = new StreamReader(_ntstream); //추출한 networkstream으로 streamreader,writer 생성
_stwriter = new StreamWriter(_ntstream);
_client.ReceiveTimeout = 500; //클라이언트의 ReceiveTimeout설정
_thread_receive = new Thread(receive); //receive메서드 스레드로 생성
_thread_receive.Start(); //스레드 시작
}
}
catch (Exception ex)
{
_connect_flag = false; //실패할경우 접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show("접속에 실패하였습니다");
}
}
void receive()
{
try
{
while (_connect_flag) //현재 접속중인지 아닌지 판단
{
string receive_data = _streader.ReadLine(); //streamreader의 한줄을 읽어들여 string 변수에 저장
if (receive_data != null) //data가 null이 아니면
{
if (receive_data.Equals(1))
{
}
tb_recevie_text(receive_data); //텍스트박스에 텍스트를 추가하는 메서드
}
}
}
catch (IOException) //IO에러 (Timeout에러도 이쪽으로 걸림)
{
if (_connect_flag) //현재 접속중인지 아닌지 체크
{
_thread_receive = new Thread(receive); //접속중일 경우 receive메서드를 이용한 스레드 다시생성
_thread_receive.Start();
}
else
{
_connect_flag = false; //접속중이 아닐경우 자연스럽게 스레드 정지
}
}
catch (Exception ex) //그 밖의 에러
{
_connect_flag = false; //접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString()); //오류 내용 보고
}
}
void tb_recevie_text(string data) //텍스트박스에 텍스트 추가하는 메서드
{
if (this.InvokeRequired)
{
this.Invoke(new D_receive(tb_recevie_text),data); //델리게이트 관련 코드로 다음번에 간단히 다시 설명하겠습니다.
}
else
{
if (data != null) //data가 null이 아닐경우
{
tb_receive.AppendText(data + "\r\n"); //텍스트박스에 데이터+개행문자 추가
}
}
}
private void bt_send_Click(object sender, EventArgs e) //전송 버튼
{
try
{
if (_connect_flag) //현재 접속중인지 아닌지 체크
{
if (tb_writeline.Text != string.Empty) //전송할 내용이 담긴 TextBox가 비었는지 체크
{
_stwriter.WriteLine(tb_writeline.Text); //StreamWriter 버퍼에 텍스트박스 내용 저장
_stwriter.Flush(); //StreamWriter 버퍼 내용을 스트림으로 전달
}
}
}
catch(Exception ex) //에러
{
_connect_flag = false; //접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString()); //에러 내용 보고
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) //FormClosing 이벤트
{
_connect_flag = false; //접속중인지 체크하는 _connect_flag를 false로 변경
}
private void tb_receive_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
}
和客户
and Client
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
namespace TCP_Client
{
public partial class Form1 : Form
{
// 각종 전역 변수 선언
NetworkStream _ntstream;
StreamReader _streader;
StreamWriter _stwriter;
Thread _thread_receive;
TcpClient _client;
bool _connect_flag = false;
delegate void D_receive(string data); //델리게이트 다음번에 자세히 설명하겠음.
public Form1()
{
InitializeComponent();
}
private void tb_connect_Click(object sender, EventArgs e)
{
try
{
if (!_connect_flag) //현재 접속중인지 아닌지 판단.(첫 접속일 경우 전역변수 선언부에서 false로 선언하였기때문에 접속중이 아님)
{
_client = new TcpClient(tb_ip.Text, int.Parse(tb_port.Text));//텍스트 박스 값으로 TcpClient 생성 (int.parse 는 텍스트를 숫자화 하는 메서드)
_connect_flag = true; //접속하였기 때문에 접속 플래그를 True로 변경
_ntstream = _client.GetStream(); //접속한 Cilent에서 networkstream을 추출
_streader = new StreamReader(_ntstream); //추출한 networkstream으로 streamreader,writer 생성
_stwriter = new StreamWriter(_ntstream);
_client.ReceiveTimeout = 500; //클라이언트의 ReceiveTimeout설정
_thread_receive = new Thread(receive); //receive메서드 스레드로 생성
_thread_receive.Start(); //스레드 시작
}
}
catch (Exception ex)
{
_connect_flag = false; //실패할경우 접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show("접속에 실패하였습니다");
}
}
void receive()
{
try
{
while (_connect_flag) //현재 접속중인지 아닌지 판단
{
string receive_data = _streader.ReadLine(); //streamreader의 한줄을 읽어들여 string 변수에 저장
if (receive_data != null) //data가 null이 아니면
{
if (receive_data.Equals(1))
{
}
tb_recevie_text(receive_data); //텍스트박스에 텍스트를 추가하는 메서드
}
}
}
catch (IOException) //IO에러 (Timeout에러도 이쪽으로 걸림)
{
if (_connect_flag) //현재 접속중인지 아닌지 체크
{
_thread_receive = new Thread(receive); //접속중일 경우 receive메서드를 이용한 스레드 다시생성
_thread_receive.Start();
}
else
{
_connect_flag = false; //접속중이 아닐경우 자연스럽게 스레드 정지
}
}
catch (Exception ex) //그 밖의 에러
{
_connect_flag = false; //접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString()); //오류 내용 보고
}
}
void tb_recevie_text(string data) //텍스트박스에 텍스트 추가하는 메서드
{
if (this.InvokeRequired)
{
this.Invoke(new D_receive(tb_recevie_text),data); //델리게이트 관련 코드로 다음번에 간단히 다시 설명하겠습니다.
}
else
{
if (data != null) //data가 null이 아닐경우
{
tb_receive.AppendText(data + "\r\n"); //텍스트박스에 데이터+개행문자 추가
}
}
}
private void bt_send_Click(object sender, EventArgs e) //전송 버튼
{
try
{
if (_connect_flag) //현재 접속중인지 아닌지 체크
{
if (tb_writeline.Text != string.Empty) //전송할 내용이 담긴 TextBox가 비었는지 체크
{
_stwriter.WriteLine(tb_writeline.Text); //StreamWriter 버퍼에 텍스트박스 내용 저장
_stwriter.Flush(); //StreamWriter 버퍼 내용을 스트림으로 전달
}
}
}
catch(Exception ex) //에러
{
_connect_flag = false; //접속이 취소되었음으로 플래그를 false로 변경
MessageBox.Show(ex.ToString()); //에러 내용 보고
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) //FormClosing 이벤트
{
_connect_flag = false; //접속중인지 체크하는 _connect_flag를 false로 변경
}
private void tb_writeline_TextChanged(object sender, EventArgs e)
{
}
}
}
我的问题是如果我向服务器发送消息,Server-Form2 Popup但它不能互相通信
我怎么能解决它??
and my problem is if i send message to server, Server- Form2 Popup but it cant communicate each other
how could i solve it:?
答
在这里你去:使用C#的TCP / IP聊天应用程序 [ ^ ]
祝你好运,
Edo
Here you go: TCP/IP Chat Application Using C#[^]
Good luck,
Edo