要求:
1.可以完成一对一的通信;
2.实现服务端对客户端一对多的选择发送;
3.可以实现服务端的群发功能;
4.可以实现客户端文件的发送;

要点:
服务器端:
第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第二步:建立一个Socket对像;
第三步:用socket对像的Bind()方法绑定EndPoint;
第四步:用socket对像的Listen()方法开始监听;
第五步:接受到客户端的连接,用socket对像的Accept()方法创建新的socket对像用于和请求的客户端进行通信;
第六步:通信结束后一定记得关闭socket;

客户端:
第一步:用指定的端口号和服务器的ip建立一个EndPoint对像;
第二步:建立一个Socket对像;
第三步:用socket对像的Connect()方法以上面建立的EndPoint对像做为参数,向服务器发出连接请求;
第四步:如果连接成功,就用socket对像的Send()方法向服务器发送信息;
第五步:用socket对像的Receive()方法接受服务器发来的信息 ;
第六步:通信结束后一定记得关闭socket;

服务端代码如下:

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 Socket_ServerAndClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
} Thread threadWatch = null;
Socket socketWatch = null; /// <summary>
/// 创建服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
socketWatch = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPAddress address = IPAddress.Parse(txtIP.Text.Trim());
IPEndPoint endpoint = new IPEndPoint(address,int.Parse(txtPort.Text.Trim()));
socketWatch.Bind(endpoint);
socketWatch.Listen(10);
threadWatch = new Thread(WatchConnection);
threadWatch.IsBackground = true;
threadWatch.Start();
ShowMsg("服务器监听成功......");
} //Socket sokConnection = null;
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
Dictionary<string, Thread> dictThread = new Dictionary<string, Thread>(); /// <summary>
/// 监听客户端的请求方法
/// </summary>
/// <param name="obj"></param>
private void WatchConnection(object obj)
{
while (true)
{
// 负责通信的套接字
Socket sokConnection = socketWatch.Accept();
lb_Online.Items.Add(sokConnection.RemoteEndPoint.ToString());
dict.Add(sokConnection.RemoteEndPoint.ToString(),sokConnection); //创建通信线程
ParameterizedThreadStart pts = new ParameterizedThreadStart(RecMsg);// 委托
Thread thr = new Thread(pts);
thr.IsBackground = true;
thr.Start(sokConnection);
dictThread.Add(sokConnection.RemoteEndPoint.ToString(),thr); ShowMsg("客户端连接成功......"+sokConnection.RemoteEndPoint.ToString());
}
} /// <summary>
/// 服务端负责监听客户端发送消息的方法
/// </summary>
void RecMsg(object socketClient)
{
Socket socketClients = socketClient as Socket;
while (true)
{
byte[] arrMsgRec = new byte[1024 * 1024 * 2]; int length = -1;
try
{
length = socketClients.Receive(arrMsgRec);
}
catch (SocketException ex)
{
ShowMsg("异常:" + ex.Message);
// 从 通信套接字 集合中删除被中断连接的套接字对象
dict.Remove(socketClients.RemoteEndPoint.ToString());
// 从 通信线程 集合中删除被中断连接的套接字对象
dictThread.Remove(socketClients.RemoteEndPoint.ToString());
// 从 列表 中移除 IP&Port
lb_Online.Items.Remove(socketClients.RemoteEndPoint.ToString());
break;
}
catch (Exception ex)
{
ShowMsg("异常:" + ex.Message);
break;
}
// 判断第一个发送过来的数据如果是1,则代表发送过来的是文本数据
if (arrMsgRec[0] == 0)
{
string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length-1);
ShowMsg(strMsgRec);
}
// 若是1则发送过来的是文件数据(文档,图片,视频等。。。)
else if(arrMsgRec[0] == 1)
{
// 保存文件选择框对象
SaveFileDialog sfd = new SaveFileDialog();
// 选择文件路径
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// 获得保存文件的路径
string fileSavePath = sfd.FileName;
// 创建文件流,然后让文件流根据路径创建一个文件
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
{
fs.Write(arrMsgRec, 1, length - 1);
ShowMsg("文件保存成功:"+fileSavePath);
}
}
}
}
} private void ShowMsg(string p)
{
txtMsg.AppendText(p+"\r\n");
} /// <summary>
/// 发送消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Send_Click_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(lb_Online.Text))
{
MessageBox.Show("请选择发送的好友!!!");
}
else
{
string strMsg = tb_Msg_Send.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
string strClientKey = lb_Online.Text;
try
{
dict[strClientKey].Send(arrMsg);
ShowMsg("发送了数据出去:"+strMsg);
}
catch (SocketException ex)
{
ShowMsg("发送时异常:" + ex.Message);
}
catch(Exception ex)
{
ShowMsg("发送时异常:" + ex.Message);
}
// sokConnection.Send(arrMsg);
ShowMsg("发送了数据出去:"+strMsg);
}
} /// <summary>
/// 群发消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SendToAll_Click(object sender, EventArgs e)
{
string strMsg = txtMsg.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
foreach (Socket item in dict.Values)
{
item.Send(arrMsg);
}
ShowMsg("群发完毕!!!:)");
}
}
}

  

客户端代码如下:

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 Socket_Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;
} Thread threadRec = null;
Socket socketClient = null; private void btn_Connect_Click(object sender, EventArgs e)
{
IPAddress address = IPAddress.Parse(tb_IP.Text.Trim());
IPEndPoint endport = new IPEndPoint(address,int.Parse(tb_Port.Text.Trim()));
socketClient = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
socketClient.Connect(endport); threadRec = new Thread(RecMsg);
threadRec.IsBackground = true;
threadRec.Start();
} void RecMsg()
{
while (true)
{
byte[] arrMsgRec = new byte[1024*1024*2];
int length = socketClient.Receive(arrMsgRec);
string strMsgRec = System.Text.Encoding.UTF8.GetString(arrMsgRec,0,length);
ShowMsg(strMsgRec);
}
} private void ShowMsg(string msg)
{
tb_Msg.AppendText(msg+"\r\n");
} private void btnSendMsg_Click(object sender, EventArgs e)
{
string strMsg = txtMsgSend.Text.Trim();
byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg);
byte[] arrMsgSend = new byte[arrMsg.Length];
// 添加标识位,0代表发送的是文字
arrMsgSend[0] = 0;
Buffer.BlockCopy(arrMsg, 0, arrMsgSend, 1, arrMsg.Length);
socketClient.Send(arrMsg);
ShowMsg("I say:"+strMsg);
} /// <summary>
/// 选择文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btChoseFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtFilePath.Text = ofd.FileName;
}
} /// <summary>
/// 发送文件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btSendFile_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream())
{
byte[] arrFile = new byte[1024*1024*2];
int length = fs.Read(arrFile, 0, arrFile.Length);
byte[] arrFileSend = new byte[length+1];
arrFileSend[0] = 1;// 代表文件数据
// 将数组 arrFile 里的数据从第零个数据拷贝到 数组 arrFileSend 里面,从第1个开始,拷贝length个数据
Buffer.BlockCopy(arrFile, 0, arrFileSend, 1, length);
socketClient.Send(arrFileSend);
}
}
}
}

程序运行截图:

  

(C#:Socket)简单的服务端与客户端通信。的更多相关文章

  1. Netty 学习(二):服务端与客户端通信

    Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...

  2. C#Winform窗体实现服务端和客户端通信例子(TCP/IP)

    Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...

  3. C# 编写WCF简单的服务端与客户端

    http://www.wxzzz.com/1860.html Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Win ...

  4. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...

  5. socket创建UDP服务端和客户端

    UDP服务端代码示例: from socket import * #1.创建数据报套接字 sockfd = socket(AF_INET, SOCK_DGRAM) #2.绑定服务端地 sockfd.b ...

  6. socket创建TCP服务端和客户端

    看情况选择相对应的套接字*面向连接的传输--tcp协议--可靠的--流式套接字(SOCK_STREAM)*面向无连接的传输--udp协议--不可靠的--数据报套接字(SOCK_DGRAM) 在liun ...

  7. go --socket通讯(TCP服务端与客户端的实现)

    这篇文章主要使用Go语言实现一个简单的TCP服务器和客户端.服务器和客户端之间的协议是 ECHO, 这个RFC 862定义的一个简单协议.为什么说这个协议很简单呢, 这是因为服务器只需把收到的客户端的 ...

  8. C# Socket简单例子(服务器与客户端通信)

    这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消 ...

  9. java网络编程-单线程服务端与客户端通信

    该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...

随机推荐

  1. ucos调度器详解

    这一片谈谈关于ucos调度器的相关知识. ucos的调度器的实现主要靠一个函数OS_Sched 该函数将调度器的行为分为了两个部分,第一是调度部分,第二是任务切换部分,如下 void  OS_Sche ...

  2. 利用OpenSSL创建证书链并应用于IIS7

    一.系统环境说明 Linux & OpenSSL Linux localhost -.el5 # SMP Tue Mar :: EDT x86_64 x86_64 x86_64 GNU/Lin ...

  3. android 菜单的总结

    安卓菜单有三种菜单. 选项菜单: 点击系统菜单按钮会触发 上下文菜单:长按屏幕触发 子菜单:某一个菜单的下一级菜单 具体的描叙:http://blog.csdn.net/zqiang_55/artic ...

  4. zend framework 1.10项目配置与经典hello world

    准备工作 前置条件:PHP>=5.14,Apache开启mod_rewrite支持,开启php的pdo扩展. Zend Framework 要求 PHP版本不低于5.1.4,但强烈建议使用 5. ...

  5. Practice Round China New Grad Test 2014 报告

    今天有Google of Greater China Test for New Grads of 2014的练习赛,主要是为了过几天的校园招聘测试做练习用的,帮助熟悉平台,题目嘛,个人觉得除了A题外, ...

  6. linux 5个查找命令

    1. find find是最常见和最强大的查找命令,你可以用它找到任何你想找的文件. find的使用格式如下: $ find <指定目录> <指定条件> <指定动作> ...

  7. Python装饰器学习(九步入门)

    这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- coding:gbk -*- '''示 ...

  8. iOS 使用 github

    1. 创建 github 账号 登陆官网 https://github.com 进行创建. 2. 创建 github 仓库 3. 添加Pods依赖库所需文件 4. github 之 下载历史版本 5. ...

  9. PosixIO

    1.打开文件 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t m ...

  10. HTTP协议缓存策略深入详解之ETAG妙用

    Etag是什么: Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等.具体内部含义是使服务器控制的,就像Cookie那样. HTTP协议规格说明定义 ...