网络编程之TCP异步群聊:服务器端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。
该程序可以在公共网络上运行,只要输入服务器的IP地址即可。
程序不是很难,由于时间过了一年多了,现在也不好详细讲解了。就贴一下代码,程序还是很容易理解的,看英文单词就知道代码的意思了。
客户端代码在:http://blog.csdn.net/arsenal1109389480/article/details/12400385
第一步:建一个Winform程序
第二步:添加一个类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Net.Sockets; namespace server
{
class StreamObject
{
public TcpClient client;
public NetworkStream netStream;
public byte[] readBytes;
public byte[] writeBytes; public StreamObject(TcpClient client)
{
this.client = client;
netStream = client.GetStream();
readBytes = new byte[client.ReceiveBufferSize];
writeBytes = new byte[client.SendBufferSize];
} public void InitReadArray()
{
readBytes = new byte[client.ReceiveBufferSize];
} public void InitWriteArray()
{
writeBytes = new byte[client.SendBufferSize];
}
}
}
第三步:服务器代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO; namespace server
{
public partial class ServerMain : Form
{
System.Collections.ArrayList clientList = new System.Collections.ArrayList(); Thread ServerThread; private delegate void SetListBoxStatuCallback(string str);
private SetListBoxStatuCallback setlistboxstatucallback;
private delegate void SetListBoxRecieveCallback(string str);
private SetListBoxRecieveCallback setlistboxrecievecallback; bool isExit = false;
private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset); public ServerMain()
{
InitializeComponent(); setlistboxstatucallback = new SetListBoxStatuCallback(SetListboxStatu);
setlistboxrecievecallback = new SetListBoxRecieveCallback(SetListboxRecieve);
} private void ServerMain_Load(object sender, EventArgs e)
{
startlisten.Enabled = true;
stoplisten.Enabled = false;
labelstatu.Text = "等待运行......";
} private void startlisten_Click(object sender, EventArgs e)
{
startlisten.Enabled = false;
stoplisten.Enabled = true; ThreadStart ts = new ThreadStart(AcceptConnect);
ServerThread = new Thread(ts);
ServerThread.Start();
} private void AcceptConnect()
{ TcpListener listener;
IPAddress IP = IPAddress.Parse("127.0.0.1"); listener = new TcpListener(IP, Convert.ToInt32(portText.Text));
listener.Start(); while (isExit == false)
{
try
{
allDone.Reset();
AsyncCallback callback = new AsyncCallback(AcceptTcpClient);
listBoxStatus.Invoke(setlistboxstatucallback, "开始等待用户连接"); listener.BeginAcceptTcpClient(callback, listener);
allDone.WaitOne();
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
}
} private void AcceptTcpClient(IAsyncResult ar)
{
try
{
allDone.Set();
TcpListener myListener = (TcpListener)ar.AsyncState;
TcpClient myclient = myListener.EndAcceptTcpClient(ar); listBoxRecieve.Invoke(setlistboxrecievecallback,
"已接受客户连接" + myclient.Client.RemoteEndPoint); StreamObject streamobject = new StreamObject(myclient); clientList.Add(streamobject); SendString("用户"+myclient.Client.RemoteEndPoint+"进入服务器"); streamobject.netStream.BeginRead(streamobject.readBytes,
0, streamobject.readBytes.Length, ReadCallback, streamobject);
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
} private void ReadCallback(IAsyncResult ar)
{
try
{
StreamObject streamobject = (StreamObject)ar.AsyncState;
int count = streamobject.netStream.EndRead(ar); SendString(string.Format("[来自{0}]{1}", streamobject.client.Client.RemoteEndPoint,
System.Text.Encoding.UTF8.GetString(streamobject.readBytes,
0, count))); if (isExit == false)
{
streamobject.InitReadArray();
streamobject.netStream.BeginRead(streamobject.readBytes,
0, streamobject.readBytes.Length, ReadCallback, streamobject);
}
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
} private void SendString(string str)
{
StreamObject streamobject; for(int i=0;i<clientList.Count;i++)
{
streamobject = (StreamObject)clientList[i];
try
{
streamobject.writeBytes = System.Text.Encoding.UTF8.GetBytes(str);
streamobject.netStream.BeginWrite(streamobject.writeBytes, 0,
streamobject.writeBytes.Length,
new AsyncCallback(SendCallback), streamobject);
streamobject.netStream.Flush();
}
catch
{
clientList.RemoveAt(i);
SendString(string.Format("用户{0}离开服务器。",streamobject.client.Client.RemoteEndPoint));
streamobject.netStream.Close();
}
}
} private void SendCallback(IAsyncResult ar)
{
StreamObject streamobject = (StreamObject)ar.AsyncState;
try
{
streamobject.netStream.EndWrite(ar);
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
} private void SetListboxStatu(string str)
{
listBoxStatus.Items.Add(str);
listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1;
listBoxStatus.ClearSelected();
} private void SetListboxRecieve(string str)
{
listBoxRecieve.Items.Add(str);
listBoxRecieve.SelectedIndex = listBoxRecieve.Items.Count - 1;
listBoxRecieve.ClearSelected();
} private void stoplisten_Click(object sender, EventArgs e)
{
//使线程自动结束
isExit = true;
//将事件状态设置为终止状态,允许一个或者多个等待线程继续
//从而使线程正常结束
allDone.Set();
startlisten.Enabled = true;
stoplisten.Enabled = false;
}
}
}
网络编程之TCP异步群聊:服务器端代码的更多相关文章
- 网络编程之TCP异步群聊:客户端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档.于是我也觉的有这个必要.写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客 ...
- java 26 - 6 网络编程之 TCP协议 传输思路 以及 代码
TCP传输 Socket和ServerSocket 建立客户端和服务器 建立连接后,通过Socket中的IO流进行数据的传输 关闭socket 同样,客户端与服务器是两个独立的应用程序 TCP协议发送 ...
- Java网络编程之TCP
Java网络编程之TCP TCP主要需要两个类:Socket和ServerSocket,Socket是客户端连接服务器时创建,参数需要指定服务器的ip和端口,ServerSocket是服务器端创建 ...
- java网络编程之TCP通讯
java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...
- 网络编程之TCP编程
网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...
- Java网络编程之TCP、UDP
Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载. ...
- 网络编程之TCP/IP各层详解
网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只 ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- Java网络编程之TCP通信
一.概述 Socket类是Java执行客户端TCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信.Socket类的方法会建立和销毁连接,设置各种Socket选项. Server ...
随机推荐
- JAVA 环境变量
Java是由Sun公司开发的一种应用于分布式网络环境的程序设计语言,Java语言拥有跨平台的特性,它编译的程序能够运行在多种操作系统平台上,可以实现“一次编写,到处运行”的强大功能. 工具/原料 JD ...
- nim
上帝创造了一个n*m棋盘,每一个格子都只有可能是黑色或者白色的. 亚当和夏娃在玩一个游戏,每次寻找边长为x的正方形,其中每个格子必须为黑色,然后将这些格子染白. 如果谁不能操作了,那么那个人就输了. ...
- Mac OS X 开启SSH服务
系统偏好设置-->共享 没解锁的解个锁 选中远程登录&允许所有用户 若要远程登录这台电脑, 请键入 ssh 要登录的用户名@ip地址或电脑名,例:ssh zhanghua@applede ...
- python【第三篇】函数
内容大纲: 1.函数基本语法与特性 2.参数与局部变量 3.返回值 4.递归 5.匿名函数lambda 6.函数式编程介绍 7.高阶函数 8.内置函数 1.函数基本语法与特性 函数的定义:函数是指将一 ...
- Day12(补充) Python操作MySQL
本篇对于Python操作MySQL主要使用两种方式: 原生模块 pymsql ORM框架 SQLAchemy pymsql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb ...
- 如何调整iMindMap打印设置
打印何尝不是一种保存.导出iMindMap思维导图的一种方法,我们还可以通过调整打印设置来满足我们不同的需求.下面小编就给你翻一翻iMindMap中文版教程,教你怎样调整打印设置. 我们在打开iMin ...
- 转:理解 PHP 中的 Streams
本文转自:开源中国社区 [http://www.oschina.net]本文标题:理解 PHP 中的 Streams 本文地址:http://www.oschina.net/translate/und ...
- BZOJ 3872 Ant colony
Description There is an entrance to the ant hill in every chamber with only one corridor leading int ...
- Hotel
poj3667:http://poj.org/problem?id=3667 题目大意:Hotel有N(1 ≤ N ≤ 50,000)间rooms,并且所有的rooms都是连续排列在同一边,group ...
- IIC总线协议
前言:年前给老师做个红外抄表系统,,现在对当中用到的一些模块总结一下. 1.只有在总线空闲时才允许启动数据传送. 2.在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允许有跳变.时钟线 ...