分享
 
 
 

C#聊天程序

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

/*=====================================================================

文件: Wintalk.cs

摘要: 演示如何使用 .NET创建聊天程序

=====================================================================*/

using System;

using System.IO;

using System.Text;

using System.Threading;

using System.Net;

using System.Net.Sockets;

using System.Drawing;

using System.Windows.Forms;

class App{

// Entry point

public static void Main(String[] args){

// If the args parse in known way then run the app

if(ParseArgs(args)){

// Create a custom Talker object

Talker talker = new Talker(endPoint, client);

// Pass the object reference to a new form object

TalkForm form = new TalkForm(talker);

// Start the talker "talking"

talker.Start();

// Run the applications message pump

Application.Run(form);

}

}

// Parsed Argument Storage

private static IPEndPoint endPoint;

private static bool client;

// Parse command line arguments

private static bool ParseArgs(String[] args){

try{

if(args.Length == 0){

client = false;

endPoint = new IPEndPoint(IPAddress.Any,5150);

return true;

}

switch(Char.ToUpper(args[0][1])){

case 'L':

int port = 5150;

if(args.Length > 1){

port = Convert.ToInt32(args[1]);

}

endPoint = new IPEndPoint(IPAddress.Any,port);

client = false;

break;

case 'C':

port = 5150;

String address = "127.0.0.1";

client = true;

if(args.Length > 1){

address = args[1];

port = Convert.ToInt32(args[2]);

}

endPoint = new IPEndPoint(Dns.Resolve(address).AddressList[0], port);

break;

default:

ShowUsage();

return false;

}

}catch{

ShowUsage();

return false;

}

return true;

}

// Show sample usage

private static void ShowUsage(){

MessageBox.Show("WinTalk [switch] [parameters...]\n\n"+

" /L [port]\t\t-- Listens on a port. Default: 5150\n"+

" /C [address] [port]\t-- Connects to an address and port.\n\n"+

"Example Server - \n"+

"Wintalk /L\n\n"+

"Example Client - \n"+

"Wintalk /C ServerMachine 5150","WinTalk Usage");

}

}

// UI class for the sample

class TalkForm:Form {

public TalkForm(Talker talker) {

// Associate for method with the talker object

this.talker = talker;

talker.Notifications += new

Talker.NotificationCallback(HandleTalkerNotifications);

// Create a UI elements

Splitter talkSplitter = new Splitter();

Panel talkPanel = new Panel();

receiveText = new TextBox();

sendText = new TextBox();

// we'll support up to 64k data in our text box controls

receiveText.MaxLength = sendText.MaxLength = 65536;

statusText = new Label();

// Initialize UI elements

receiveText.Dock = DockStyle.Top;

receiveText.Multiline = true;

receiveText.ScrollBars = ScrollBars.Both;

receiveText.Size = new Size(506, 192);

receiveText.TabIndex = 1;

receiveText.Text = "";

receiveText.WordWrap = false;

receiveText.ReadOnly = true;

talkPanel.Anchor = (AnchorStyles.Top|AnchorStyles.Bottom

|AnchorStyles.Left|AnchorStyles.Right);

talkPanel.Controls.AddRange(new Control[] {sendText,

talkSplitter,

receiveText});

talkPanel.Size = new Size(506, 371);

talkPanel.TabIndex = 0;

talkSplitter.Dock = DockStyle.Top;

talkSplitter.Location = new Point(0, 192);

talkSplitter.Size = new Size(506, 6);

talkSplitter.TabIndex = 2;

talkSplitter.TabStop = false;

statusText.Dock = DockStyle.Bottom;

statusText.Location = new Point(0, 377);

statusText.Size = new Size(507, 15);

statusText.TabIndex = 1;

statusText.Text = "Status:";

sendText.Dock = DockStyle.Fill;

sendText.Location = new Point(0, 198);

sendText.Multiline = true;

sendText.ScrollBars = ScrollBars.Both;

sendText.Size = new Size(506, 173);

sendText.TabIndex = 0;

sendText.Text = "";

sendText.WordWrap = false;

sendText.TextChanged += new EventHandler(HandleTextChange);

sendText.Enabled = false;

AutoScaleBaseSize = new Size(5, 13);

ClientSize = new Size(507, 392);

Controls.AddRange(new Control[] {statusText,

talkPanel});

Text = "WinTalk";

this.ActiveControl = sendText;

}

// When the app closes, dispose of the talker object

protected override void OnClosed(EventArgs e){

if(talker!=null){

// remove our notification handler

talker.Notifications -= new

Talker.NotificationCallback(HandleTalkerNotifications);

talker.Dispose();

}

base.OnClosed(e);

}

// Handle notifications from the talker object

private void HandleTalkerNotifications(

Talker.Notification notify, Object data){

switch(notify){

case Talker.Notification.Initialized:

break;

// Respond to status changes

case Talker.Notification.StatusChange:

Talker.Status status = (Talker.Status)data;

statusText.Text = String.Format("Status: {0}", status);

if(status == Talker.Status.Connected){

sendText.Enabled = true;

}

break;

// Respond to received text

case Talker.Notification.Received:

receiveText.Text = data.ToString();

receiveText.SelectionStart = Int32.MaxValue;

receiveText.ScrollToCaret();

break;

// Respond to error notifications

case Talker.Notification.Error:

Close(data.ToString());

break;

// Respond to end

case Talker.Notification.End:

MessageBox.Show(data.ToString(), "Closing WinTalk");

Close();

break;

default:

Close();

break;

}

}

// Handle text change notifications and send talk

private void HandleTextChange(Object sender, EventArgs e){

if(talker != null){

talker.SendTalk((sender as TextBox).Text);

}

}

// Close with an explanation

private void Close(String message){

MessageBox.Show(message, "Error!");

Close();

}

// Private UI elements

private TextBox receiveText;

private TextBox sendText;

private Label statusText;

private Talker talker;

}

// An encapsulation of the Sockets class used for socket chatting

class Talker:IDisposable{

// Construct a talker

public Talker(IPEndPoint endPoint, bool client){

this.endPoint = endPoint;

this.client = client;

socket = null;

reader = null;

writer = null;

statusText = prevSendText = prevReceiveText = String.Empty;

}

// Finalize a talker

~Talker(){

Dispose();

}

// Dispose of resources and surpress finalization

public void Dispose(){

GC.SuppressFinalize(this);

if(reader != null){

reader.Close();

reader = null;

}

if(writer != null){

writer.Close();

writer = null;

}

if(socket != null){

socket.Close();

socket = null;

}

}

// Nested delegat class and matchine event

public delegate

void NotificationCallback(Notification notify, Object data);

public event NotificationCallback Notifications;

// Nested enum for notifications

public enum Notification{

Initialized = 1,

StatusChange,

Received,

End,

Error

}

// Nested enum for supported states

public enum Status{

Listening,

Connected

}

// Start up the talker's functionality

public void Start(){

ThreadPool.QueueUserWorkItem(new WaitCallback(EstablishSocket));

}

// Send text to remote connection

public void SendTalk(String newText){

String send;

// Is this an append

if((prevSendText.Length <= newText.Length) && String.CompareOrdinal(

newText, 0, prevSendText, 0, prevSendText.Length)==0){

String append = newText.Substring(prevSendText.Length);

send = String.Format("A{0}:{1}", append.Length, append);

// or a complete replacement

}else{

send = String.Format("R{0}:{1}", newText.Length, newText);

}

// Send the data and flush it out

writer.Write(send);

writer.Flush();

// Save the text for future comparison

prevSendText = newText;

}

// Send a status notification

private void SetStatus(Status status){

this.status = status;

Notifications(Notification.StatusChange, status);

}

// Establish a socket connection and start receiving

private void EstablishSocket(Object state){

try{

// If not client, setup listner

if(!client){

Socket listener;

try{

listener = new Socket(AddressFamily.InterNetwork,

SocketType.Stream, ProtocolType.Tcp);

listener.Blocking = true;

listener.Bind(endPoint);

SetStatus(Status.Listening);

listener.Listen(0);

socket = listener.Accept();

listener.Close();

}catch(SocketException e){

// If there is already a listener on this port try client

if(e.ErrorCode == 10048){

client = true;

endPoint = new IPEndPoint(

Dns.Resolve("127.0.0.1").AddressList[0], endPoint.Port);

}else{

Notifications(

Notification.Error,

"Error Initializing Socket:\n"+e.ToString());

}

}

}

// Try a client connection

if(client){

Socket temp = new

Socket(AddressFamily.InterNetwork,

SocketType.Stream,ProtocolType.Tcp);

temp.Blocking = true;

temp.Connect(endPoint);

socket = temp;

}

// If it all worked out, create stream objects

if(socket != null){

SetStatus(Status.Connected);

NetworkStream stream = new NetworkStream(socket);

reader = new StreamReader(stream);

writer = new StreamWriter(stream);

Notifications(Notification.Initialized, this);

}else{

Notifications(Notification.Error,

"Failed to Establish Socket");

}

// Start receiving talk

// Note: on w2k and later platforms, the NetworkStream.Read()

// method called in ReceiveTalk will generate an exception when

// the remote connection closes. We handle this case in our

// catch block below.

ReceiveTalk();

// On Win9x platforms, NetworkStream.Read() returns 0 when

// the remote connection closes, prompting a graceful return

// from ReceiveTalk() above. We will generate a Notification.End

// message here to handle the case and shut down the remaining

// WinTalk instance.

Notifications(Notification.End, "Remote connection has closed.");

}catch(IOException e){

SocketException sockExcept = e.InnerException as SocketException;

if(sockExcept != null && 10054 == sockExcept.ErrorCode){

Notifications(Notification.End, "Remote connection has closed.");

}else{

if (Notifications != null)

Notifications(Notification.Error, "Socket Error:\n"+e.Message);

}

}catch(Exception e){

Notifications(Notification.Error, "Socket Error:\n"+e.Message);

}

}

// Receive chat from remote client

private void ReceiveTalk(){

char[] commandBuffer = new char[20];

char[] oneBuffer = new char[1];

int readMode = 1;

int counter = 0;

StringBuilder text = new StringBuilder();

while(readMode != 0){

if(reader.Read(oneBuffer, 0, 1)==0){

readMode = 0;

continue;

}

switch(readMode){

case 1:

if(counter == commandBuffer.Length){

readMode = 0;

continue;

}

if(oneBuffer[0] != ':'){

commandBuffer[counter++] = oneBuffer[0];

}else{

counter = Convert.ToInt32(

new String(commandBuffer, 1, counter-1));

if(counter>0){

readMode = 2;

text.Length = 0;

}else if(commandBuffer[0] == 'R'){

counter = 0;

prevReceiveText = String.Empty;

Notifications(Notification.Received, prevReceiveText);

}

}

break;

case 2:

text.Append(oneBuffer[0]);

if(--counter == 0){

switch(commandBuffer[0]){

case 'R':

prevReceiveText = text.ToString();

break;

default:

prevReceiveText += text.ToString();

break;

}

readMode = 1;

Notifications(Notification.Received, prevReceiveText);

}

break;

default:

readMode = 0;

continue;

}

}

}

private Socket socket;

private TextReader reader;

private TextWriter writer;

bool client;

IPEndPoint endPoint;

private String prevSendText;

private String prevReceiveText;

private String statusText;

private Status status;

}

Microsoft.NET FrameworkSDK带这个例子.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有