基于c#用Socket做一个局域网聊天工具_C#教程

程序设计成为简单的服务端和客户端之间的通信, 但通过一些方法可以将这两者进行统一起来, 让服务端也成为客户端, 让客户端也成为服务端, 使它们之间可以互相随时不间断的通信. 考虑到实现最原始的服务端和客户端之间的通信所需要的步骤对于写这样的程序是很有帮助的.

作为服务端, 要声明一个Socket A并绑定(Bind)某一个IP+这个IP指定的通信端口, 比如这个是127.0.0.1:9050, 然后开始监听(Listen), Listen可以监听来自多个IP传过来的连接请求, 具体可以同时连接几个客户端, Listen方法中可以设定一个参数. 如果Listen到某一个客户端发来连接请求了, 这时定义一个新的Socket B专门负责与这个客户端的通信, Socket B = A.Accept(). 这时可以获取这个客户端的IP和端口,  IPEndPoint C = (IPEndPoint)B.RemoteEndPoint, C.Address和C.Port分别表示客户端C的IP地址和端口. 这时通过B.Send()方法就可以给C发送消息了, B.Receive()可以接收客户端C发来的信息.

作为客户端, 也需要声明一个Socket D并绑定某一个IP+本机一个未被占用的端口, 定义IPEndPoint E表示要进行连接的服务端Socket, 要指明E的IP和端口, 这样才可以进行端口对端口之间的通信, 接下来就可以尝试D.Connect(E), 连接成功之后就可以发送和接收数据了, D.Send(), D.Receive.

发送消息时, 数据都是以字节或字节数组为单位进行传输的, 比如我客户端D要发送"Hello World"则要这样写: D.Send(Encoding.ASCII.GetBytes("Hello World")).  接受消息时, 也是以字节或字节数组, 比如服务端要接受D刚才发送的Hello World, 可以这样写: Byte[] data = new Byte[1024]; int receivedDataLength = B.Receive(data); string stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength); stringdata这时就是Hello World.

上面只是大概的阐述了服务端与客户端之间的通信过程, 在网上找到了具体的代码例子, 也贴过来参考参考. 这个例子没有将服务端与客户端统一起来, 他是分别写服务端和客户端的.

服务端代码

using System;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace tcpserver
{
   ///  <summary>
   /// Class1 的摘要说明。
   ///  </summary>
   class server
  {
     ///  <summary>
     /// 应用程序的主入口点。
     ///  </summary>
    [STAThread]
     static  void Main( string [] args)
    {
       //
       // TODO: 在此处添加代码以启动应用程序
       //
      int recv; // 用于表示客户端发送的信息长度
      byte [] data;// = new  byte [ 1024 ]; // 用于缓存客户端所发送的信息,通过socket传递的信息必须为字节数组
      IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050 ); // 本机预使用的IP和端口
      Socket newsock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
      newsock.Bind(ipep); // 绑定
      newsock.Listen( 10 ); // 监听
      Console.WriteLine( " waiting for a client " );
      Socket client = newsock.Accept(); //当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信
      IPEndPoint clientip = (IPEndPoint)client.RemoteEndPoint;
      Console.WriteLine( " connect with client: " + clientip.Address + " at port: " + clientip.Port);
      string welcome = " welcome here! " ;
      data = Encoding.ASCII.GetBytes(welcome);
      client.Send(data,data.Length,SocketFlags.None); // 发送信息
      while ( true )
      { // 用死循环来不断的从客户端获取信息
        data = new  byte [ 1024 ];
        recv = client.Receive(data);
        Console.WriteLine( " recv= " + recv);
        if (recv == 0 ) // 当信息长度为0,说明客户端连接断开
           break ;
        Console.WriteLine(Encoding.ASCII.GetString(data, 0 ,recv));
        client.Send(data,recv,SocketFlags.None);
      }
      Console.WriteLine( " Disconnected from " + clientip.Address);
      client.Close();
      newsock.Close();
    }
  }
}

客户端代码

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace tcpclient
{
  ///  <summary>
  /// Class1 的摘要说明。
  ///  </summary>
  class client
  {
    ///  <summary>
    /// 应用程序的主入口点。
    ///  </summary>
    [STAThread]
    static void Main(string[] args)
    {
      //
      // TODO: 在此处添加代码以启动应用程序
      //
      byte[] data = new byte[1024];
      Socket newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
      newclient.Bind(new IPEndPoint(IPAddress.Any, 905));
      Console.Write(" please input the server ip: ");
      string ipadd = Console.ReadLine();
      Console.WriteLine();
      Console.Write(" please input the server port: ");
      int port = Convert.ToInt32(Console.ReadLine());
      IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port); // 服务器的IP和端口
      try
      {
        // 因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。
        newclient.Connect(ie);
      }
      catch (SocketException e)
      {
        Console.WriteLine(" unable to connect to server ");
        Console.WriteLine(e.ToString());
        return;
      }
      int receivedDataLength = newclient.Receive(data);
      string stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength);
      Console.WriteLine(stringdata);
      while (true)
      {
        string input = Console.ReadLine();
        if (input == " exit ")
          break;
        newclient.Send(Encoding.ASCII.GetBytes(input));
        data = new byte[1024];
        receivedDataLength = newclient.Receive(data);
        stringdata = Encoding.ASCII.GetString(data, 0, receivedDataLength);
        Console.WriteLine(stringdata);
      }
      Console.WriteLine(" disconnect from sercer ");
      newclient.Shutdown(SocketShutdown.Both);
      newclient.Close();
    }
  }
}

上面的服务端和客户端都是控制台应用程序, 想办法做一个窗体类型的, 思路就是另起一个线程, 这个线程专门负责两端建立连接. 如果不采用另起线程的方法, 当等待连接而没有连接上, 或者主动连接, 服务端还没有相应时, 程序就会出现没有响应的假死状态.

当这个线程将两个端口连接成功后, 就让程序进入一个死循环, 这个死循环负责不断的接收是否有消息传来, 传来的话就在txtGetMsg中显示出来:

while (true)  // 用死循环来不断的获取信息
{
  data = new byte[1024];
  recv = newclient.Receive(data);

  uiContext.Send(new SendOrPostCallback(
  state =>
  {
    int txtGetMsgLength = txtGetMsg.Text.Length;
    string recMsg = "Friend:    " + System.DateTime.Now.ToString() + "\n  " +Encoding.Unicode.GetString(data, 0, recv) + "\n";
    txtGetMsg.AppendText(recMsg);
    txtGetMsg.Select(txtGetMsgLength, recMsg.Length - Encoding.Unicode.GetString(data, 0, recv).Length - 1);
    txtGetMsg.SelectionColor = Color.Red;
  }), null);
}

如果按下发送消息的按钮, 则发送txtSendMsg中的文本, 我写的是用Unicode编码, 所以可以发送中文字符.

private void btnSendMsg_Click(object sender, EventArgs e)
{
  string input = txtSendMsg.Text;
  if (input == "")
  {
    MessageBox.Show("消息不能为空!", "发送消息出错");
    txtSendMsg.Focus();
  }
  else
  {
    if (meIsClient)
    {
      newclient.Send(Encoding.Unicode.GetBytes(input));
      string showText = "Me:      " + System.DateTime.Now.ToString() + "\n  "
      + input + "\n";
      int txtGetMsgLength = txtGetMsg.Text.Length;
      txtGetMsg.AppendText(showText);
      txtGetMsg.Select(txtGetMsgLength, showText.Length - 1 - input.Length);
      txtGetMsg.SelectionColor = Color.Blue;
      txtSendMsg.Text = "";
    }
    else
    {
      client.Send(Encoding.Unicode.GetBytes(input));
      string showText = "Me    " + System.DateTime.Now.ToString() + "\n  "
      + input + "\n";
      int txtGetMsgLength = txtGetMsg.Text.Length;
      txtGetMsg.AppendText(showText);
      txtGetMsg.Select(txtGetMsgLength, showText.Length - 1 - input.Length);
      txtGetMsg.SelectionColor = Color.Blue;
      txtSendMsg.Text = "";
    }
  }
}

程序的运行效果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索聊天
, socket聊天程序
, c#局域网聊天程序
c#socket
c、汇编语言、基于c语言ug二次开发、基于c 的gis系统、c 基于类的通讯录,以便于您获取更多的相关知识。

时间: 2024-08-31 07:09:39

基于c#用Socket做一个局域网聊天工具_C#教程的相关文章

通信-C#基于TCP的局域网聊天工具 不知道怎么接收消息部分怎么写 求设计思路

问题描述 C#基于TCP的局域网聊天工具 不知道怎么接收消息部分怎么写 求设计思路 我之所以问这个问题是因为我说的接收消息不是那种两个窗口都开着 发送或接收的 而是当接收的用户不在场时 聊天窗口并未打开也能接收 只是好友列表里的好友在闪 然后等用户回来 点击好友时聊天窗口,好友发送过来的那些信息还有 然后用户也能回复 说白了就是qq那样的 我只能做到发送信息 和当发送消息,接收方的用户里对应的好友在闪(只是在闪 也不能接收消息和打开窗口) 想问问大侠们 如果是你们大概会怎么设计这一块 .....

求用pb或c#做的局域网聊天软件源代码

问题描述 寻求一个用pb或c#做的局域网聊天软件源代码,功能有:聊天.传送文件.语音. 解决方案 解决方案二:好象没有这么完整的.解决方案三:建议用java吧,C#的使用者们估计还没有这么强的开源精神.看看java的openfire和spark吧,都是开源的解决方案四:openfire和spark不只支持前述的功能,视频聊天也支持的解决方案五:资料带源码,绝对完整,直接可以编译http://blog.csdn.net/HeddaZ/archive/2008/04/23/2317343.aspx解

图片搜索-做一个图片服务器,求教程~~

问题描述 做一个图片服务器,求教程~~ 小弟我是软件开发实习的,以前没做过类似的项目,各位大神们能否给我推荐一些Java开发图片服务器的书籍.文章,最好有例程~~ 要求存储量大.并发量高. 解决方案 java系统高并发解决方案之图片服务器分离 http://blog.csdn.net/jimmy609/article/details/37909013 解决方案二: 可以采用nginx,做缓存,适合高并发 你数据再存为文件或其他 解决方案三: 这么啥教程.你的需求也不明确. 如果是静态文件服务,不

c-在用ffmpeg 2.0做一个转码工具的时候,转出的视频 视频播放速度变快

问题描述 在用ffmpeg 2.0做一个转码工具的时候,转出的视频 视频播放速度变快 在用最新版 ffmpeg 2.0 转换视频的时候 首先遇到的一个问题是 在 avformat_write_header(pFormatCtxOut NULL); 处报错:[mp4 @ 0x8183600] track 1: codec frame size is not set 虽然报了这个错误 但是还是能够转码,只是转出来的视频本来30秒 但是15秒左右就没有了,应该没有丢帧,只不过画面播放得特别快,就像快进

想用VC++.NET做一个流程图绘制工具,请高人指教

问题描述 是这样的,毕业设计课题是制作一个基于对象的图像工具,其实就是做一个流程图工具,要实现的功能不多,能绘制些基本图形.连线.输入文字即可,上网搜了些资料,也参考了些流程图工具,但还是感觉不知从何入手,哪位大哥能提供些好的资料给我参考参考.先谢了- 解决方案 解决方案二:不会,我也想学这个!如知道也请告诉我谢谢!keywa@126.com解决方案三:office里面不是有一个现成的吗?解决方案四:http://www.skinfeature.com/bbs这里有例子下载解决方案五:谁有嵌入所

C#局域网聊天工具制作系列讲座(4)_托盘

问题描述 现在很多程序都有托盘功能,而我们的聊天工具更是如此,无论是QQ,旺旺,飞鸽传书等等,都是以托盘的形式工作在后台,对消息进行监听的.而VS2005给我们提供了现成的控件,来完成托盘的功能,下面我结合代码讲解下项目中可能用到的托盘技巧.1.如何实现托盘功能:在VS2005中直接添加notifyIcon控件,然后设置下icon属性,给其设置个图标即可,使用托盘功能.但是托盘并不能实现我们要求的功能,具体的功能实现,需要我们手工添加代码实现.2.如何最小化时自动到托盘privatevoidFo

Visual C#.Net 网络程序开发-Socket篇第1/2页_C#教程

Visual C#.Net 网络程序开发-Socket篇   作者: 宋华  作者: www.ASPCool.com  Microsoft.Net Framework为应用程序访问Internet提供了分层的.可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类可以开发多种网络应用程序..Net类采用的分层结构允许应用程序在不同的控制级别上访问网络,开发人员可以根据需要选择针对不同的级别编制程序,这些级别几乎囊括了Internet的所有需

java基于Socket做一个简单下载器_java

本文实例为大家分享了java基于Socket制作下载器的过程,及相关代码,供大家参考,具体内容如下 1.首先要建立一个服务器用来处理信息并给客户端传输文件(电脑)  我是用电脑开了一个WIFI,手机连上后使用scoket传输的  SERVERIP要根据自己实际情况更改.端口也可以随便更改0~65535,尽量选大一点  import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.Bu

有没有朋友帮我导入demo?做一个简单聊天app

问题描述 我的qq  1061385816   远程协助,有偿服务 解决方案 @beyond ,  简单demo啥时候出?解决方案二:关于简版demo 已经修改了两版了,在做最后的确认,这周争取上传.不过我看这位同学的问题不是简版demo解决的,是不知道怎么做没思路吗?可以再社区发帖把问题详细列出来,社区里面有很多热心的大牛,也可以到官网咨询环信技术支持,有一群热心的技术支持解决哈.吐过是想找人远程有偿帮助,我给你推荐一个哈江南孤鹜解决方案三:简单聊天app 官方demo可以实现,不过如果是需要