基于socket实现的简单的聊天程序
记得八年前第一次使用socket做的一个五子棋程序,需要序列化棋子对象,传递到对方的电脑上。 一个偶然的机会,第二次使用socket做点事情。先看聊天服务器端的实现:
服务器端要实现以下功能:
1、启动服务,开启监听
2、持续不断地接收消息
3、发送消息
启动服务,创建监听socket,绑定Ip和端口:
/// <summary>
/// 启动服务
/// </summary>
private void Start()
{
socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress address = IPAddress.Parse("10.0.0.31"); IPEndPoint point = new IPEndPoint(address, ); socketwatch.Bind(point); //将套接字的监听队列长度限制为20
socketwatch.Listen(); //创建一个监听线程
threadwatch = new Thread(watchconnecting); threadwatch.IsBackground = true; threadwatch.Start();
}
创建接收数据的Socket:
//监听客户端发来的请求
private void watchconnecting()
{
Socket connection = null;
while (true) //持续不断监听客户端发来的请求
{
try
{
connection = socketwatch.Accept();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); //提示套接字监听异常
break;
}
//获取客户端的IP和端口号
IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port; //让客户显示"连接成功的"的信息
string sendmsg = "连接服务端成功!\r\n" + "本地IP:" + clientIP + ",本地端口" + clientPort.ToString();
byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
connection.Send(arrSendMsg); RemoteEndPoint = connection.RemoteEndPoint.ToString(); //客户端网络结点号
dic.Add(RemoteEndPoint, connection); //添加客户端信息 IPEndPoint netpoint = connection.RemoteEndPoint as IPEndPoint; //创建一个通信线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(recv);
Thread thread = new Thread(pts);
thread.IsBackground = true;//设置为后台线程,随着主线程退出而退出
//启动线程
thread.Start(connection);
}
}
socketwatch.Accept() 会创建一个新的socket,它用来负责和某个客户端的通讯。 接收数据:
private void recv(object socketclientpara)
{ Socket socketServer = socketclientpara as Socket;
while (true)
{
byte[] arrServerRecMsg = new byte[ * ];
try
{
int length = socketServer.Receive(arrServerRecMsg); string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, , length); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart)delegate()
{
MessagePool.Insert(MessagePool.Count, new Message() { MessageInfo = strSRecMsg, IdentityName = socketServer.RemoteEndPoint.ToString() });
});
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
socketServer.Close();
break;
}
}
}
把从客户端接收过来的字节流变为字符串,然后添加到页面上。
发送消息:
private static object lockPool = new object();
public static ObservableCollection<Message> MessagePool = new ObservableCollection<Message>();
private void send_Click(object sender, RoutedEventArgs e)
{
string msg = this.message.Text; this.message.Clear(); lock (lockPool)
{
MessagePool.Insert(MessagePool.Count, new Message() { MessageInfo = msg, IdentityName = "wbq" });
} string sendMsg = msg;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sendMsg); if (dic.Count > )
dic.First().Value.Send(bytes);
}
dic.First().Value.Send,从字典中获取到之前创建好的通讯socket,然后调用send方法。 客户端需要实现以下功能:
1、和服务器建立连接
2、接收数据
3、发送数据 建立连接:
private void Start()
{ //定义一个套接字监听
socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); var servers= GetServers(); if (servers.Count > )
{ //获取文本框中的IP地址
IPAddress address = IPAddress.Parse(servers.First().IPToPing); //将获取的IP地址和端口号绑定在网络节点上
IPEndPoint point = new IPEndPoint(address, int.Parse(servers.First().Port)); try
{
//客户端套接字连接到网络节点上,用的是Connect
socketclient.Connect(point);
}
catch (Exception)
{
//MessageBox.
MessageBox.Show("连接失败\r\n");
return;
} threadclient = new Thread(recv); threadclient.IsBackground = true; threadclient.Start();
}
}
接收消息:
// 接收服务端发来信息的方法
private void recv()//
{
while (true)//持续监听服务端发来的消息
{
try
{
//定义一个1M的内存缓冲区,用于临时性存储接收到的消息
byte[] arrRecvmsg = new byte[ * ]; //将客户端套接字接收到的数据存入内存缓冲区,并获取长度
int length = socketclient.Receive(arrRecvmsg); //将套接字获取到的字符数组转换为人可以看懂的字符串
string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, , length); this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart)delegate()
{
MessagePool.Insert(MessagePool.Count, new Message() { MessageInfo = strRevMsg, IdentityName = socketclient.RemoteEndPoint.ToString() });
});
}
catch (Exception ex)
{
MessageBox.Show("远程服务器已经中断连接" + ex.Message);
break;
}
}
}
发送消息:
private void send_Click(object sender, RoutedEventArgs e)
{
string strRevMsg = this.message.Text;
this.message.Clear(); lock (lockPool)
{
MessagePool.Insert(MessagePool.Count, new Message() { MessageInfo = strRevMsg, IdentityName = "我(" + socketclient.LocalEndPoint.ToString() + ")" });
} //将输入的内容字符串转换为机器可以识别的字节数组
byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(strRevMsg);
//调用客户端套接字发送字节数组
socketclient.Send(arrClientSendMsg);
}
经过和同事的测试,可以实现简单的文字聊天,此代码仅为测试代码,若要用于实际的项目中,需要很大改进,比如socket异步建立,消息接收和发送等等。
基于socket实现的简单的聊天程序的更多相关文章
- [JavaWeb基础] 024.Socket编程之简单的聊天程序
1.Socket的简介 1)什么是Socket 网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket.Socket通常用来实现客户方和服务方的连接.Socket ...
- python socket编程 实现简单p2p聊天程序
目标是写一个python的p2p聊天的项目,这里先说一下python socket的基础课程 一.Python Socket 基础课程 Socket就是套接字,作为BSD UNIX的进程通信机制,取后 ...
- Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程
SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...
- 简单的聊天程序,主要用到的是Socket
服务端: import java.io.*; import java.net.*; import java.util.*; public class ChatServer { boolean stat ...
- C#编写简单的聊天程序
这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...
- C#编写简单的聊天程序(转)
这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...
- 使用Ajax long polling实现简单的聊天程序
关于web实时通信,通常使用长轮询或这长连接方式进行实现. 为了能够实际体会长轮询,通过Ajax长轮询实现了一个简单的聊天程序,在此作为笔记. 长轮询 传统的轮询方式是,客户端定时(一般使用setIn ...
- Java网络编程以及简单的聊天程序
网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ...
- Udp实现简单的聊天程序
在<UDP通讯协议>这篇文章中,简单的说明了Udp协议特征及如何Udp协议传输数据 这里将用Udp协议技术,编写一个简单的聊天程序: //发送端: package com.shindo.j ...
随机推荐
- PPPoE拨号流程
PPPoE(Point to Point Protocol over Ethernet,基于以太网的点对点协议)的工作流程包含发现(Discovery)和会话(Session)两个阶段,发现阶段是无状 ...
- Java经典编程题50道之二十二
利用递归方法求5!. public class Example22 { public static void main(String[] args) { int n = 5; ...
- cassandra 鉴权
1. 修改cassandra.yaml配置文件.启用用户密码登录形式. authenticator: PasswordAuthenticator authorizer: CassandraAuthor ...
- spring注解-@Transactional事务几点注意
这里面有几点需要大家留意:A. 一个功能是否要事务,必须纳入设计.编码考虑.不能仅仅完成了基本功能就ok.B. 如果加了事务,必须做好开发环境测试(测试环境也尽量触发异常.测试回滚),确保事务生效.C ...
- Java爬虫----有道翻译初步
目标:http://fanyi.youdao.com/ 用爬虫实现翻译功能. 利用f12查看网页Network,可以发现 有关翻译的表单请求通过 http://fanyi.youdao.com/tr ...
- 剑指offer第五天
28.数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数 ...
- NJU 1010 Air
思路:把那张图打表(吐血...),然后就按照规则输出就行. AC代码 #include <cstdio> #include <cmath> #include <cctyp ...
- Spring data mongodb @CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy SpringSecurityAuditorAware,只记录用户名
要在Spring data mongodb 中使用@CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy 这四个注解 必须实现 SpringSecuri ...
- 位置信息类API调用的代码示例合集:中国省市区查询、经纬度地址转换、POI检索等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 中国省市区查询:2017最新中国省市区地址 经纬度地址转换:经纬度 ...
- 2015最全iOS开发自学视频资料(基础+实战)
最全的iOS自学视频,包括c,objective-c,UI等等,没有你找不到的,只有你学不会的,只要你想学,这里都有你所需要的. 推荐教程点这里:http://www.mobiletrain.org/ ...