C#_Socket网络编程实现的简单局域网内即时聊天,发送文件,抖动窗口。

最近接触了C#Socket网络编程,试着做了试试(*^__^*)

实现多个客户端和服务端互相发送消息

发送文件
抖动窗口功能  

服务端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace kehuduan
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Dictionary<string,Socket> dicsocket = new Dictionary<string, Socket>();//键值集合,通过键能找到值
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                //创建监听的socket
                Socket socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //获得ip地址
                IPAddress ip = IPAddress.Any;//Parse(textBox1.Text);
                //创建端口号对象
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox2.Text));
                socketwatch.Bind(point);
                showmsg(DateTime.Now.ToString() + "监听成功");//192.168.1.103:监听成功
                socketwatch.Listen(10);//开始监听。监听队列10人

                //开启新线程解决卡顿
                Thread lis = new Thread(Listen);
                lis.IsBackground = true;
                lis.Start(socketwatch);
            }
            catch
            {

            }
        }
        Socket socketsend;
        /// <summary>
        /// 循环等待接入的客户端
        /// </summary>
        /// <param name="o"></param>
        void Listen(object o)
        {
            try
            {
                Socket socketwatch = o as Socket;
                while (true)
                {
                    //负责跟客户端通信的Socket
                    socketsend = socketwatch.Accept();
                    //把连进来的socket存到建值集合和下拉菜单中,实现给指定的客户端发消息
                    dicsocket.Add(socketsend.RemoteEndPoint.ToString(),socketsend);
                    comboBox1.Items.Add(socketsend.RemoteEndPoint.ToString());//socket.remoteendpoint可以显示socket的ip地址和端口号
                    //192.168.1.103:连接成功
                    showmsg(socketsend.RemoteEndPoint.ToString() + ":" + "连接成功");
                    //连接成功后开启新线程接受消息
                    Thread th = new Thread(Recive);
                    th.IsBackground = true;
                    th.Start(socketsend);

                }
            }
            catch { }

        }
        /// <summary>
        /// 服务器端循环接收客户端发来的信息
        /// </summary>
        /// <param name="o"></param>
        void Recive(object o)
        {
            while (true)
            {
                try
                {
                    Socket socketsend = o as Socket;
                    byte[] b = new byte[1024 * 1024 * 2];
                    //实际接收到的有效字节
                    int r = socketsend.Receive(b);
                    if (r == 0)
                    {
                        break;
                    }
                    string str = Encoding.UTF8.GetString(b, 0, r);
                    showmsg(socketsend.RemoteEndPoint.ToString() + "说:" + str);
                }
                catch
                {

                }
            }
        }
        /// <summary>
        /// 往文本框里添加文字的方法
        /// </summary>
        /// <param name="a"></param>
        void showmsg(string a)
        {
            textBox3.AppendText(a+"\r\n");
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        /// <summary>
        /// 服务器给客户端发文字消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                List<byte> nb = new List<byte>();
                string str = textBox4.Text.Trim();
                byte[] b = System.Text.Encoding.UTF8.GetBytes(str);
                nb.Add(0);
                nb.AddRange(b);
                byte[] newb = nb.ToArray();
                string ip = comboBox1.SelectedItem.ToString();
                dicsocket[ip].Send(newb);
                //socketsend.Send(b);
                showmsg("我说 :" + str);
            }
            catch { }
        }
        /// <summary>
        /// 选择要发送的文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd  = new OpenFileDialog();

            ofd.InitialDirectory = @"C:\Documents and Settings\Administrator\桌面";
            ofd.Title = "请选择要发送的文件";
            ofd.Filter = "所有文件|*.*";
            ofd.ShowDialog(this);//加this
            textBox5.Text = ofd.FileName;

        }
        /// <summary>
        /// 向客户端发送文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                string path = textBox5.Text;
                using (FileStream fsread = new FileStream(path, FileMode.Open, FileAccess.Read)) //把文件转换为文件流
                {
                    byte[] b = new byte[1024 * 1024 * 5];//最大5m的文件
                    int r = fsread.Read(b, 0, b.Length);
                    List<byte> nb = new List<byte>();
                    nb.Add(1);//在第一位加上数字,让客户端可以识别服务端的指令
                    nb.AddRange(b);//往集合中添加集合的方法。
                    byte[] newb = nb.ToArray();
                    dicsocket[comboBox1.SelectedItem.ToString()].Send(newb, 0, r + 1, SocketFlags.None);
                }

            }
            catch { }

        }
        /// <summary>
        /// 抖动窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)//发送消息
        {
            try
            {
                byte[] b = new byte[1];
                b[0] = 2;
                dicsocket[comboBox1.SelectedItem.ToString()].Send(b);
            }
            catch { }

        }
    }
}

客户端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace kehuduan
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Socket socketsend;
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                socketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//设置一个socket

                IPAddress ip = IPAddress.Parse(textBox1.Text);//将文本框中的字符串转换成IP地址。
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(textBox2.Text));//创建IPEndpoint对象实例。包含ip地址和端口号
                socketsend.Connect(point);//连接到IPendpoint所在的监听socket
                showmsg("连接成功");
//开启新线程
                Thread th = new Thread(Recive);
                th.IsBackground = true;
                th.Start();
            }
            catch { }

        }

        void showmsg(string str)  //在文本框中添加内容
        {
            textBox3.AppendText(str+"\r\n");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;//取消跨线程使用控件检查。
        }
        void Recive()//接收
        {
            while (true)
            {
                try
                {

                    byte[] b = new byte[1024 * 1024 * 2];
                    //实际接收到的有效字节
                    int r = socketsend.Receive(b);
                    if (r == 0)
                    {
                        break;
                    }
                    if (b[0] == 0)
                    {
                        string str = Encoding.UTF8.GetString(b, 1, r-1);  //从第二个开始截取,因为第一个元素用来判断服务端发过来的指令。
                        showmsg(socketsend.RemoteEndPoint.ToString() + "说:" + str);
                    }
                    else if (b[0] == 1)
                    {
                        SaveFileDialog sfd = new SaveFileDialog();//保存文件对话框
                        sfd.InitialDirectory = @"C:\Documents and Settings\Administrator\桌面";
                        sfd.Title = "对方发送了一个文件,请选择保存的位置";
                        sfd.ShowDialog();

                        string path = sfd.FileName;
                        using (FileStream fswrite = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))//数据流控制,用来保存文件。
                        {
                            fswrite.Write(b,1,r-1);
                            MessageBox.Show("保存成功");
                        }

                    }
                    else if (b[0] == 2)//如果发来的字节包首个元素的值==2,就振动
                    {
                        ZD();
                    }
                }
                catch
                {

                }
            }
        }

        private void button2_Click(object sender, EventArgs e)//发送消息
        {
            try
            {
                string str = textBox4.Text.Trim();//存下文本框中的内容
                byte[] b = System.Text.Encoding.UTF8.GetBytes(str);//将内容转换成二进制流(utf8编码)
                socketsend.Send(b);//发送给服务端
                showmsg("我说 :" + str);//将我说的话放到文本框中
            }
            catch { }
        }
        /// <summary>
        /// 震动窗体
        /// </summary>
        void ZD()//连续修改窗口的Location,模拟抖动窗口效果
        {
            for (int i = 0; i < 50; i++)
            {

                Point a = this.Location;
                a.X += 5;
                a.Y += 5;
                this.Location = a;
                Thread.Sleep(2);
                a.X -=5;
                a.Y -=5;
                this.Location = a;
            }
        }
    }
}

知识点

//跨线程使用控件应在窗口加载时取消检查。

//跨线程方法传值只能传Object类型的值,可以在方法中强制转换成需要的类型,如 socketwatch = Object AS socket(将AS前的对象转换成后边的对象,如果成功返回转换成功后的对象,否则返回null)

//键值集合

  Dictionary<键,值> 集合名 = new Dictionary<键, 值>();集合名.add(键,值)//往集合里添加使用 集合名[键] 可以访问键对应的值。
时间: 2024-10-05 06:04:25

C#_Socket网络编程实现的简单局域网内即时聊天,发送文件,抖动窗口。的相关文章

【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [实验目的] 1.熟练掌握线程的创建与终止方法: 2.熟练掌握线程间通信同步方法: 3.应用套接字函数完成多线程服务器,实现服务器与客户端的信息交互. [实验内容] 通过一个服务器实现最多5个客户之间的信息群发. 服务器显示客户的登录与退出: 客户连接后首先发送客户名称,之后发送群聊信息: 客户输入bye代表退

Android 网络编程基础之简单聊天程序

前一篇讲了Android的网络编程基础,今天写了一个简单的聊天程序分享一下 首先是服务端代码: 1 package com.jiao.socketdemo; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStreamWriter;

java网络编程——socket实现简单的CS会话

还记得当年学计网课时用python实现一个简单的CS会话功能,这也是学习socket网络编程的第一步,现改用java重新实现,以此记录. 客户端 import java.io.*; import java.net.Inet4Address; import java.net.InetSocketAddress; import java.net.Socket; public class Client { public static void main(String[] args)throws IOE

TCP/IP网络编程读书笔记-简单的套接字编程(1)

在linux和windows下都是通过套接字编程进行网络编程.不同的系统上通信有部分差别,现在刚开始学习,给自己学习的时候一个总结. 一,socket函数的套接字步骤 第一,linux网络编程中接受连接请求(服务器端)套接字的四个步骤: 1)调用socket函数创建套接字 2)调用bind函数分配IP地址和端口号 3)调用listen函数转为可接收请求状态 4)调用accept函数受理连接请求 第二,linux网络编程中请求连接(客户端)套接字的两个步骤: 1)调用socket函数创建套接字 2

网络编程TCP/IP实现客户端与客户端聊天

一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那么首先要考虑的是如何准确的定位到网络上的一台或几台主机,另一个是如何进行可靠高效的数据传输.这里就要使用到TCP/IP协议. TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成.IP层负责网络主机的定位,数据传输的路由,由IP地址可以唯一的确定Internet上的一台主机.TCP层负责面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象. 二.TCP与UDP TCP是一种面向连接的保证可靠传输的协议

局域网内基于UDP的文件传输小工具

一.目标 基于UDP来设计一个文件传输的小工具,以此来了解UDP协议的特点. 内容: 基本要求: 输入对方IP地址,对方如果存在,可以给对方发送文件. 扩展要求: (1)工具具有友好的用户界面: (2)局域网内使用该工具的两台主机可以互相进行文字通信: (3)自动按照一定频率扫描局域网内其他开启了该工具的主机,并在界面上用列表显示出来: (4)传输文件和文字内容时,直接选择界面上已经显示出来的存活主机,不需要手动输入IP地址. 二.设计实现 环境: Ubuntu14.04+Gcc4.8+Ecli

linux网络编程1 最简单的socket编程

下面是socket编程的服务器端 先看一个图,1 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<unistd.h> //针对系统调用的封装 fork,pipe 各种i/o原语 read write 等 5 6 #include<sys/socket.h> 7 #include<netinet/in.h> //互联网地址族 定义数据结构s

【网络编程笔记】简单的TCP协议 socket编程(C语言版服务器和客户端)

下图是一般socket 编程图. 服务器的建立: 获取的本机名,用来解析得到本机的IP地址的:接着就绑定IP地址成功,然后服务器就处于监听状态,等待客户端的连接.也就是接下来就是TCP/IP的三次握手的操作,该操作成功了服务器和客户端就可以进行通信了.以下是注释代码: 1 void socketConnect() 2 { 3 char Server_name[128]; 4 WSADATA wsaData; 5 struct hostent *hp; 6 struct sockaddr_in a

linux 网络编程之最简单的tcp通信服务端

编写一个最为简单的tcp通信服务端.代码如下: #include <iostream> #include <cstring> using namespace std; #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <uni