제가 서버를 하려고 하고있는데 크로스 쓰래드 문제가 생겨서 invoke를 <div>해봤는데 이게 이제 연결은 되는데 문자가 떠야 될 부분들이 안뜨네요 ;;</div> <div><span style="font-size:9pt;line-height:1.5;"> </span>using System;</div> <div>using System.Collections.Generic;</div> <div>using System.ComponentModel;</div> <div>using System.Data;</div> <div>using System.Drawing;</div> <div>using System.Linq;</div> <div>using System.Text;</div> <div>using System.Threading.Tasks;</div> <div>using System.Windows.Forms;</div> <div><br></div> <div>using System.Net; // IPAddress</div> <div>using System.Net.Sockets; //TcpListener 클래스사용</div> <div>using System.Threading; //스레드 클래스 사용</div> <div>using System.IO; //파일 클래스 사용</div> <div><br></div> <div>namespace WindowsFormsApplication4</div> <div>{</div> <div><br></div> <div> public partial class Form1 : Form</div> <div> {</div> <div> private TcpListener Server; //TCP 네트워크 클라이언트에서 연결 수신</div> <div> private TcpClient SerClient; //TCP 네트워크 서비스에 대한 클라이언트 연결 제공</div> <div> private NetworkStream myStream; //네트워크 스트림</div> <div> private StreamReader myRead; //스트림 읽기</div> <div> private StreamWriter myWrite; //스트림 쓰기</div> <div> private Boolean Start = false; //서버 시작</div> <div> private Boolean ClientCon = false; //클라이언트 시작</div> <div> private int myPort; //포트</div> <div> private string myName; //별칭(ID)</div> <div> private Thread myReader, myServer; //스레드</div> <div> private Boolean TextChange = false; //입력 컨트롤의 데이터입력 체크</div> <div> private delegate void AddTextDele(string str);</div> <div> private AddTextDele AddText;</div> <div><br></div> <div> public Form1()</div> <div> {</div> <div> InitializeComponent();</div> <div> }</div> <div><br></div> <div> private void 설정ToolStripMenuItem_Click(object sender, EventArgs e)</div> <div> {</div> <div> this.설정ToolStripMenuItem.Enabled = false;//메뉴비활성화</div> <div> this.plOption.Visible = true;//설정을 위한 상자 open</div> <div> this.txtId.Focus();//id입력상자로 초점이동</div> <div><br></div> <div> }</div> <div><br></div> <div> private void btnSave_Click(object sender, EventArgs e)</div> <div> {</div> <div> ControlCheck();</div> <div> }</div> <div> private void ControlCheck()</div> <div> {</div> <div> if (this.txtId.Text == "")//ID가 입력되지 않았으면 ID입력</div> <div> {</div> <div> this.txtId.Focus();</div> <div> }</div> <div> else if (this.txtPort.Text == "")//PORT가 입력되지 않았으면 PORT입력</div> <div> {</div> <div> this.txtPort.Focus();</div> <div> }</div> <div> else</div> <div> {</div> <div> try</div> <div> {</div> <div> this.plOption.Visible = false;//설정이 완료되었으므로 설정상자를 비활성화</div> <div> this.설정ToolStripMenuItem.Enabled = true;//상위메뉴바 활성화</div> <div> this.tsbtnConn.Enabled = true;//연결메뉴 활성화</div> <div> }</div> <div> catch</div> <div> {//에러메세지 박스 출력</div> <div> MessageBox.Show("설정이 저장되지 않았습니다.", "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);</div> <div> }</div> <div> }</div> <div> }</div> <div><br></div> <div> private void btnClose_Click(object sender, EventArgs e)</div> <div> {</div> <div> this.설정ToolStripMenuItem.Enabled = true; //설정 메뉴 활성화</div> <div> this.plOption.Visible = false; //입력창 닫기</div> <div> this.txtMessage.Focus();</div> <div> }</div> <div><br></div> <div> private void tsbtnConn_Click(object sender, EventArgs e)</div> <div> {</div> <div> var addr = new IPAddress(0);//IPAddress 클래스의 개체를 초기화, 매개변수가 0->로컬단말의 아이피 가져옴</div> <div> this.myName = this.txtId.Text;</div> <div> this.myPort = Convert.ToInt32(this.txtPort.Text);</div> <div> if (!(this.Start))//서버가 시작되지 않은 경우 </div> <div> {</div> <div> try</div> <div> {</div> <div> Server = new TcpListener(addr, this.myPort);//ip주소와 포트번호를 인자로 TcpLIstener의 개체 생성</div> <div> Server.Start();//Server 시작</div> <div><br></div> <div> this.Start = true;</div> <div> this.txtMessage.Enabled = true;</div> <div> this.btnSend.Enabled = true;</div> <div> this.txtMessage.Focus();//메시지를 쓸 수 있도록 초점을 이동</div> <div> this.tsbtnDisconn.Enabled = true;//연결을 끊을 수 있도록 메뉴 활성화</div> <div> this.tsbtnConn.Enabled = false;//연결시도버튼 비활성화</div> <div> //Thread클래스의 생성자를 이용하여 개체생성-> ServerStart()메서드로 클라이언트의 수신과 네트워크 스트림의 값을 수신하는 작업을 새로 생성한 스레스에서 수행 </div> <div> myServer = new Thread(ServerStart);</div> <div> myServer.Start();</div> <div> this.설정ToolStripMenuItem.Enabled = false;</div> <div> }</div> <div> catch</div> <div> {</div> <div> MessageView("서버를 실행할 수 없습니다.");</div> <div> }</div> <div> }</div> <div> else</div> <div> {</div> <div> ServerStop(); //ServerStop() 함수 호출</div> <div> }</div> <div><br></div> <div> }</div> <div><br></div> <div> private void MessageView(string strText)</div> <div> {</div> <div> this.rtbText.AppendText(strText + "\r\n");//입력한 텍스트와 엔터키추가</div> <div> this.rtbText.Focus();//초점이동</div> <div> this.rtbText.ScrollToCaret();// 컨트롤의 내용을 현재 캐럿 위치까지 스크롤</div> <div> this.txtMessage.Focus();//초점이동</div> <div> }</div> <div> private void ServerStart()</div> <div> { //메세지출력</div> <div> rtbText.Invoke(AddText, "서버 실행 : 챗 상대의 접속을 기다립니다...");</div> <div> while (Start)//클라이언트가 접속될 때까지 기다림</div> <div> {</div> <div> try</div> <div> {</div> <div> SerClient = Server.AcceptTcpClient();//보류중인 연결요청을 받아들임</div> <div> rtbText.Invoke(AddText, "챗 상대 접속..");</div> <div> myStream = SerClient.GetStream();//데이터를 보내고 받는 데 사용한 NetworkStream을 반환하여 myStream 개체에 대입</div> <div><br></div> <div> myRead = new StreamReader(myStream);//읽기 스트림</div> <div> myWrite = new StreamWriter(myStream);//저장 스트림</div> <div> this.ClientCon = true;//클라이언트 연결 허용</div> <div><br></div> <div> myReader = new Thread(Receive);//스레드를 이용하여 myReader개체를 생성</div> <div> myReader.Start();</div> <div> }</div> <div> catch { }</div> <div> }</div> <div> }</div> <div> private void ServerStop() // 서버 모드 종료</div> <div> {</div> <div> this.Start = false;</div> <div> this.txtMessage.Enabled = false;</div> <div> this.txtMessage.Clear();</div> <div> this.btnSend.Enabled = false;</div> <div> this.tsbtnConn.Enabled = true;</div> <div> this.tsbtnDisconn.Enabled = false;</div> <div> this.ClientCon = false;</div> <div> if (!(myRead == null))</div> <div> {</div> <div> myRead.Close(); //StreamReader 클래스 개체 리소스 해제</div> <div> }</div> <div> if (!(myWrite == null))</div> <div> {</div> <div> myWrite.Close(); //StreamWriter 클래스 개체 리소스 해제</div> <div> }</div> <div> if (!(myStream == null))</div> <div> {</div> <div> myStream.Close(); //NetworkStream 클래스 개체 리소스 해제</div> <div> }</div> <div> //복사2 붙여넣기</div> <div><br></div> <div><br></div> <div> if (!(SerClient == null))</div> <div> {</div> <div> SerClient.Close(); //TcpClient 클래스 개체 리소스 해제</div> <div> }</div> <div> if (!(Server == null))</div> <div> {</div> <div> Server.Stop(); //TcpListen 클래스 개체 리소스 해제</div> <div> }</div> <div> if (!(myReader == null))</div> <div> {</div> <div> myReader.Abort(); //외부 스레드 종료</div> <div> }</div> <div> if (!(myServer == null))</div> <div> {</div> <div> myServer.Abort(); //외부 스레드 종료</div> <div> }</div> <div> if (!(AddText == null))</div> <div> rtbText.Invoke(AddText, "연결이 끊어졌습니다.");</div> <div> }</div> <div><br></div> <div> private void Receive()</div> <div> {</div> <div> try</div> <div> {</div> <div> while (this.ClientCon)//클라이언트의 연결이 종료될 때까지 계속 실행</div> <div> {</div> <div> if (myStream.CanRead)//스트림에서 데이터를 읽을 수 있는 경우</div> <div> {</div> <div> var msg = myRead.ReadLine();</div> <div> var Smsg = msg.Split('&');//&를 기준으로 메시지 구분</div> <div> if (Smsg[0] == "S001")//첫 구분자가 "S001“인 경우</div> <div> {</div> <div> this.tsslblTime.Text = Smsg[1];//상태바의 레이블에 날짜와 시간을 출력</div> <div> }</div> <div> else</div> <div> {</div> <div> if (msg.Length > 0) //읽은 메시지가 있는 경우 </div> <div> {</div> <div> rtbText.Invoke(AddText, Smsg[0] + " : " + Smsg[1]);//MessageView()메서드를 이용화면에 출력</div> <div> }</div> <div> this.tsslblTime.Text = "마지막으로 받은 시각:" + Smsg[2];</div> <div> }</div> <div> }</div> <div> }</div> <div> }</div> <div> catch { }</div> <div> }</div> <div><br></div> <div> private void tsbtnDisconn_Click(object sender, EventArgs e)</div> <div> {</div> <div> try</div> <div> {</div> <div> if (this.SerClient.Connected)//연결중인 상태</div> <div> {</div> <div> var dt = Convert.ToString(DateTime.Now);</div> <div> myWrite.WriteLine(this.myName + "&" + "채팅 APP가 종료되었습니다." + "&" + dt);</div> <div> myWrite.Flush();</div> <div> }</div> <div> }</div> <div> catch { }</div> <div> ServerStop();//서버종료</div> <div> this.설정ToolStripMenuItem.Enabled = true;</div> <div><br></div> <div> }</div> <div><br></div> <div> private void btnSend_Click(object sender, EventArgs e)</div> <div> {</div> <div><br></div> <div> if (this.txtMessage.Text == "")</div> <div> {</div> <div> this.txtMessage.Focus();</div> <div> }</div> <div> else</div> <div> {</div> <div> Msg_send(); //Msg_send()함수 호출</div> <div> }</div> <div><br></div> <div><br></div> <div> }</div> <div> private void Msg_send()</div> <div> {</div> <div> try</div> <div> {</div> <div> var dt = Convert.ToString(DateTime.Now);</div> <div> //아이디 & 메시지 & 날짜시간을 보냄</div> <div> myWrite.WriteLine(this.myName + "&" + this.txtMessage.Text + "&" + dt);</div> <div> myWrite.Flush();</div> <div> //서버의 rtbText(채팅창)에 id와 메시지 출력</div> <div> MessageView(this.myName + ": " + this.txtMessage.Text);</div> <div> this.txtMessage.Clear();</div> <div><br></div> <div> }</div> <div> catch</div> <div> {</div> <div> rtbText.Invoke(AddText, "데이터를 보내는 동안 오류가 발생하였습니다.");</div> <div> this.txtMessage.Clear();</div> <div> }</div> <div> }</div> <div><br></div> <div> private void txtMessage_KeyPress(object sender, KeyPressEventArgs e)</div> <div> {</div> <div> if (e.KeyChar == (char)13) //엔터 키를 누를때</div> <div> {</div> <div> e.Handled = true; //소리 없앰</div> <div> if (this.txtMessage.Text == "")</div> <div> {</div> <div> this.txtMessage.Focus();</div> <div> }</div> <div> else</div> <div> {</div> <div> Msg_send(); //Msg_send()함수 호출</div> <div> }</div> <div> }</div> <div> }</div> <div><br></div> <div> private void txtMessage_TextChanged(object sender, EventArgs e)</div> <div> {</div> <div> //입력을 안하고 있던 상황에서 입력을 시작하는 경우</div> <div> if (TextChange == false)</div> <div> {</div> <div> TextChange = true;//입력을 하고 있다고 지정</div> <div> //정보전달의 암호: S001</div> <div> myWrite.WriteLine("S001" + "&" + "상대방이 메시지 입력중입니다." + "&" + " ");</div> <div> myWrite.Flush();</div> <div> }</div> <div> else if (this.txtMessage.Text == "" && TextChange == true)</div> <div> {//메시지를 입력하지 않은 경우</div> <div> TextChange = false;</div> <div> }</div> <div> }</div> <div><br></div> <div> private void Form1_FormClosing(object sender, FormClosingEventArgs e)</div> <div> {</div> <div> ServerStop();//서버종료</div> <div> }</div> <div><br></div> <div> private void Form1_Load(object sender, EventArgs e)</div> <div> {</div> <div><br></div> <div> }</div> <div> }</div> <div><br></div> <div>}</div> <div><br></div> <div>교수님 강의 자료 보면서 따라하다가 크로스 쓰래드 문제가 생겨서 이렇게 햇는데 ;; 어디가 잘못된건지 못찾겠네요 ㅠㅠ </div> <div>혹시 아시는 분들 계신가요 ?</div>
댓글 분란 또는 분쟁 때문에 전체 댓글이 블라인드 처리되었습니다.