Asp.Net - 9.socket(聊天室)
9.1 Socket相关概念
IP地址
每台联网的电脑都有一个唯一的IP地址。
长度32位,分为四段,每段8位,用十进制数字表示,每段范围 0 ~ 255
特殊IP:127.0.0.1 用户本地网卡测试
版本:V4(32位) 和 V6(128位,分为8段,每段16位)
端口
在网络上有很多电脑,这些电脑一般运行了多个网络程序。每种网络程序都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的网络程序。
常用端口:21 FTP ,25 SMTP ,110 POP3 ,80 HTTP , 443 HTTPS
有两种常用Socket类型:
流式Socket(STREAM):
是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低
数据报式Socket(DATAGRAM):
是一种无连接的Socket,对应于无连接的UDP服务应用.不安全(丢失,顺序混乱,在接收端要分析重排及要求重发),但效率高.
9.1.1 Socket 流式(服务器端和客户端)
服务器端的Socket(至少需要两个)
一个负责接收客户端连接请求(但不负责与客户端通信)
每成功接收到一个客户端的连接便在服务端产生一个对应的负责通信的Socket
在接收到客户端连接时创建.
为每个连接成功的客户端请求在服务端都创建一个对应的Socket(负责和客户端通信).
客户端的Socket
客户端Socket
必须指定要连接的服务端IP地址和端口。
通过创建一个Socket对象来初始化一个到服务器端的TCP连接
9.1.2 Socket的通讯过程
服务器端:
•申请一个socket
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
•绑定到一个IP地址和一个端口上
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//2.2 绑定端口(其实内部就像系统端口表中注册了一个端口,并指定了当前句柄)
socketWatch.Bind(endPoint);
//2.3 设置监听队列
socketWatch.Listen(10);
•开启侦听,等待接授连接
//2.4.开始监听 此方法会阻断当前线程。知道有其他程序连接,才能执行完毕
Socket socket = socketWatch.Accept(); //【通信套接字】注意这里,Accept返回类型Socket
客户端:
•申请一个socket
•连接服务器(指明IP地址和端口号)
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//3.向服务端发送连接请求
socketWatch.Connect(endPoint);
服务器端接到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通讯,原监听socket继续监听。
9.2 使用线程调用监听套接字
监听demo
监听demo 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;//线程 namespace _02Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;//检查非法跨线程调用
} //服务端 监听套接字
Socket socketWatch = null;
//服务端 监听线程
Thread thread = null; /// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Listen_Click(object sender, EventArgs e)
{
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//2.2 绑定端口(其实内部就像系统端口表中注册了一个端口,并指定了当前句柄)
socketWatch.Bind(endPoint);
//2.3 设置监听队列
socketWatch.Listen(10);
thread = new Thread(WathchConnection);
thread.IsBackground = true;
thread.Start();
ShowMsg("服务器启动。。");
} void WathchConnection()
{
//2.4.开始监听 此方法会阻断当前线程。知道有其他程序连接,才能执行完毕
socketWatch.Accept();
ShowMsg("有客户端连接~!");
} //显示监听消息方法
void ShowMsg(string strmsg)
{
this.txt_Show.AppendText(strmsg + "\r\n");
}
}
}
9.3 客户端连接服务端
向服务端发送连接请求demo
向服务端发送连接请求demo //客户端 监听套接字
Socket socketWatch = null; private void btn_Connction_Click(object sender, EventArgs e)
{
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//3.向服务端发送连接请求
socketWatch.Connect(endPoint);
}
9.4 客户端向服务端发送消息
不足:点了一次发送后,再点就没反映了。
服务端
3.通信套接字 监听 客户端 消息
3.通信套接字 监听 客户端 消息 void WathchConnection()
{
//2.4.开始监听 此方法会阻断当前线程。知道有其他程序连接,才能执行完毕
Socket socket = socketWatch.Accept();//【通信套接字】注意这里,Accept返回类型Socket
ShowMsg("有客户端连接~!");//------------------3.通信套接字 监听 客户端 消息------------------------
//3.1 创建缓存区
byte[] arrMsg = new byte[1024 * 1024 * 1];
//3.2 接收客户端的消息,并存如缓存区。注意:Receive会阻断当前的线程
socket.Receive(arrMsg);
//3.3 将接收的消息转化为字符串
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg);
//3.4 将消息 显示到 txt_show
ShowMsg(strMsg);
} //显示监听消息方法
void ShowMsg(string strmsg)
{
this.txt_Show.AppendText(strmsg + "\r\n");
}
客户端
发送消息
发送消息 /// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Send_Click(object sender, EventArgs e)
{
string strMsg = this.txt_Input.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
socketWatch.Send(arrMsg);
}
9.5 服务端循环接收消息
解决:9.4的只能发送1次的问题
创建一个线程,还是在WathchConnection里修改
服务端循环接收消息demo
服务端循环接收消息demo void WathchConnection()
{
//2.4.开始监听 此方法会阻断当前线程。知道有其他程序连接,才能执行完毕
Socket socket = socketWatch.Accept();//【通信套接字】注意这里,Accept返回类型Socket
ShowMsg("有客户端连接~!");Thread thread2 = new Thread(ReceiveMsg);
thread2.IsBackground = true;
//有参数的线程(参数只能是object)
thread2.Start(socket);
} bool isReceive = true;
void ReceiveMsg(object o)
{
Socket socket2 = o as Socket;
//------------------3.通信套接字 监听 客户端 消息------------------------
//3.1 创建缓存区
byte[] arrMsg = new byte[1024 * 1024 * 1];
while (isReceive)
{
//3.2 接收客户端的消息,并存如缓存区。注意:Receive会阻断当前的线程
socket2.Receive(arrMsg);
//3.3 将接收的消息转化为字符串
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg);
//3.4 将消息 显示到 txt_show
ShowMsg(strMsg);
}
9.6 服务端向客户端发送消息
服务端
服务端向客户端发送消息:Server
服务端向客户端发送消息: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;//线程Z namespace _02Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;//检查非法跨线程调用
}//服务端 监听套接字
Socket socketWatch =null;
//服务端 监听线程
Thread thread = null;
//字典集合(【与客户端通信的套接字】的标识保存起来)
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
/// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Listen_Click(object sender, EventArgs e)
{
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//2.2 绑定端口(其实内部就像系统端口表中注册了一个端口,并指定了当前句柄)
socketWatch.Bind(endPoint);
//2.3 设置监听队列
socketWatch.Listen(10);
thread = new Thread(WathchConnection);
thread.IsBackground = true;
thread.Start();
ShowMsg("服务器启动。。");void WathchConnection()
}
{
//2.4.开始监听 此方法会阻断当前线程。知道有其他程序连接,才能执行完毕
Socket socket = socketWatch.Accept();//【通信套接字】注意这里,Accept返回类型Socket//------------------------4.start-------------------------
//4.1将当前连接成功的【与客户端通信的套接字】的标识保存起来,并显示在列表中
//将远程客户端的 IP和端口 字符串 存入列表
lb_OnLine.Items.Add(socket.RemoteEndPoint.ToString());
//4.2 将服务器端的通信套接字 存入 字典集合
dict.Add(socket.RemoteEndPoint.ToString(), socket);
//-----------------------4.end---------------------------ShowMsg("有客户端连接~!");
Thread thread2 = new Thread(ReceiveMsg);
thread2.IsBackground = true;
//有参数的线程(参数只能是object)
thread2.Start(socket);
} /// <summary>
/// 4.3服务端向客户端发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_ServerSend_Click(object sender, EventArgs e)
{
string strClient = lb_OnLine.Text;
if (dict.ContainsKey(strClient))
{
string strMsg = txt_ServerInput.Text.Trim();
ShowMsg("向客户端【" + strClient + "】说:" + strMsg);
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
dict[strClient].Send(arrMsg);
}
}
bool isReceive = true;
void ReceiveMsg(object o)
{
Socket socket2 = o as Socket;
//------------------3.通信套接字 监听 客户端 消息------------------------
//3.1 创建缓存区
byte[] arrMsg = new byte[1024 * 1024 * 1];
while (isReceive)
{
//3.2 接收客户端的消息,并存如缓存区。注意:Receive会阻断当前的线程
socket2.Receive(arrMsg);
//3.3 将接收的消息转化为字符串
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg).Trim();
//3.4 将消息 显示到 txt_show
ShowMsg(strMsg);
} } //显示监听消息方法
void ShowMsg(string strmsg)
{
this.txt_Show.AppendText(strmsg + "\r\n");
}
}
}
客户端
服务端向客户端发送消息:Client
服务端向客户端发送消息:Client 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;//线程 namespace _02客户端
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
}
//客户端 通信套接字
Socket socketWatch = null;
//客户端 通信线程
Thread threadMsg = null; /// <summary>
/// 连接服务器
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Connction_Click(object sender, EventArgs e)
{
//1.创建监听套接字 使用 ip4协议,流式传输,TCP连接
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口
//2.1 获取网络节点对象
IPAddress address = IPAddress.Parse(this.txt_IP.Text);
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(txt_Port.Text));
//3.向服务端发送连接请求
socketWatch.Connect(endPoint);
ShowMsg("连接服务器成功!.."); //4.4.开启通信线程
threadMsg = new Thread(ReceiveMsg);
threadMsg.IsBackground = true;
threadMsg.Start();
} bool isRec = true;
void ReceiveMsg()
{
byte[] arrMsg = new byte[1024 * 1024 * 1];
while (isRec)
{
socketWatch.Receive(arrMsg);
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg);
ShowMsg("服务端说:" + strMsg);
}
} /// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Send_Click(object sender, EventArgs e)
{
string strMsg = this.txt_Input.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
socketWatch.Send(arrMsg);
} void ShowMsg(string strmsg)
{
this.txt_Show.AppendText(strmsg + "\r\n");
}
}
}
问题:
1.不换行
获取真实长度
//3.2 接收客户端的消息,并存如缓存区。注意:Receive会阻断当前的线程
int realLength = socket2.Receive(arrMsg);
//3.3 将接收的消息转化为字符串
string strMsg = System.Text.Encoding.UTF8.GetString(arrMsg,0,realLength);
Asp.Net - 9.socket(聊天室)的更多相关文章
- Java Socket聊天室编程(二)之利用socket实现单聊聊天室
这篇文章主要介绍了Java Socket聊天室编程(二)之利用socket实现单聊聊天室的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在上篇文章Java Socket聊天室编程(一)之 ...
- Java Socket聊天室编程(一)之利用socket实现聊天之消息推送
这篇文章主要介绍了Java Socket聊天室编程(一)之利用socket实现聊天之消息推送的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下 网上已经有很多利用socket实现聊天的例子了 ...
- python socket 聊天室
socket 发送的时候,使用的是全双工的形式,不是半双工的形式.全双工就是类似于电话,可以一直通信.并且,在发送后,如果又接受数据,那么在这个接受到数据之前,整个过程是不会停止的.会进行堵塞,堵塞就 ...
- TCP/IP以及Socket聊天室带类库源码分享
TCP/IP以及Socket聊天室带类库源码分享 最近遇到个设备,需要去和客户的软件做一个网络通信交互,一般的我们的上位机都是作为客户端来和设备通信的,这次要作为服务端来监听客户端,在这个背景下,我查 ...
- 015. asp.net实现简易聊天室
通过Application和Session来实现简单的聊天室和在线用户数统计 Global.asax代码: <%@ Application Language="C#" %&g ...
- html5 WebSocket 与 PHP socket 聊天室原理
html js <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- 基于Spring 4.0 的 Web Socket 聊天室/游戏服务端简单架构
在现在很多业务场景(比如聊天室),又或者是手机端的一些online游戏,都需要做到实时通信,那怎么来进行双向通信呢,总不见得用曾经很破旧的ajax每隔10秒或者每隔20秒来请求吧,我的天呐(),这尼玛 ...
- Python socket聊天室程序
http://blog.csdn.net/calling_wisdom/article/details/42524745 今天用python的socket模块实现了一个聊天室的程序 虽然功能比较简单, ...
- 【Unity3D自学记录】Unity3D网络之Socket聊天室初探
首先创建一个服务端程序,这个程序就用VS的控制台程序做即可了. 代码例如以下: using System; using System.Collections.Generic; using System ...
随机推荐
- 剑指Offer 反转链表
题目描述 输入一个链表,反转链表后,输出链表的所有元素. 思路: 法1:用栈,压栈出栈 法2:头插法(有递归非递归2中) AC代码: /* struct ListNode { int va ...
- BZOJ 3832: [Poi2014]Rally
Sol 线段树+拓扑序. 先把图的拓扑序搞出来,然后统计从起点到该点最长链,从该点到终点的最长链,然后建个起点终点,这里跟网络流很像,把它统一到一个有起点的图中,这里也要注意下细节处理.S,T的一个边 ...
- fastx_toolkit去除测序数据中的接头和低质量的reads
高通量测序数据下机后得到了fastq的raw_data,通常测序公司在将数据返还给客户之前会做"clean"处理,即得到clean_data.然而,这些clean_data是否真的 ...
- 代码高亮插件SyntaxHighlighter
http://alexgorbatchev.com/SyntaxHighlighter/download/
- gollum安装教程
在线markdown编辑器,可以直接将该程序安装在服务器上,直接编辑完之后保存在gollum目录下 1.在线安装 sudo apt-get install ruby1.9.1 ruby1.9. ...
- phpmyadmin上传大sql文件办法
进入php5文件夹下: cd /etc/php5/apache2 #根据你当时的配置选择,比如之前配置是apache2就进入apache2,如果是cli就进入cli文件夹下 打开php.ini文件 s ...
- 一个iOS 框架介绍:MKNetworkKit
http://blog.csdn.net/kmyhy/article/details/12276287 http://blog.csdn.net/mobailwang/article/details/ ...
- Redis提供的持久化机制(RDB和AOF)
Redis提供的持久化机制 Redis是一种面向"key-value"类型数据的分布式NoSQL数据库系统,具有高性能.持久存储.适应高并发应用场景等优势.它虽然起步较晚,但发展却 ...
- 《oracle每天一练》Oracle之物化视图
相关帖子思考和跟踪 本文转自Ronger 物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实 ...
- java 调用webservice的各种方法总结
java 调用webservice的各种方法总结 几种流行的开源WebService框架Axis1,Axis2,Xfire,CXF,JWS比较 方法一:创建基于JAX-WS的webservice(包括 ...