C# Socket 编程 Sample
使用Socket通信的服务器端编程,熟悉了服务器端和客户端的通信流程,实现了收发信息、文件传送以及震动功能
服务器端先创建Socket,然后将其和本地ip地址以及端口号连接,也就是使用Bind方法,然后使用Listen方法监听。
用Accept方法接受客户端的连接申请,并且等待客户端连接(在winform中,由于Accept方法是阻塞方法,必须创建一个线程来执行,防止主窗体卡死)
客户端连接成功Accept方法会返回一个用于发送和接收消息的Socket,之后就要用这个socket进行通信
在通信过程中要像实现不同功能,比如传送文件,就要在发送的字节流中使用一定的位置来存储信息,也就是使用自己的协议,在这个案例中,取第一个字节标识信息,0代表发送信息,1代表传递文件,2代表震动窗体
服务端代码如下
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.Sockets;
using System.Net;
using System.Threading;
using System.IO; namespace ServerReview
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Socket socketSend;
private Socket socketWatch;
private Dictionary<string, Socket> socketClientList = new Dictionary<string, Socket>();
private void btnStart_Click(object sender, EventArgs e)
{
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Any;
IPEndPoint iep = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
//将套接字和本机地址绑定
socketWatch.Bind(iep);
ShowMsg("监听成功");
//用Listen监听
socketWatch.Listen();
//创建新线程不停接受客户端请求
Thread thread = new Thread(ServerAccept);
thread.IsBackground = true;
thread.Start();
}
private void ServerAccept()
{
while (true)
{
socketSend = socketWatch.Accept();
socketClientList.Add(socketSend.RemoteEndPoint.ToString(), socketSend);
cboUsers.Items.Add(socketSend.RemoteEndPoint.ToString());
ShowMsg(socketSend.RemoteEndPoint.ToString() + "连接成功");
//开启新线程不停接收消息
Thread thread = new Thread(ServerReceive);
thread.IsBackground = true;
thread.Start();
}
}
private void ServerReceive()
{
while (true)
{
try
{
byte[] buffer = new byte[ * * ];
int byteNum = socketSend.Receive(buffer);
if (byteNum == )
{
break;
}
string str = Encoding.UTF8.GetString(buffer, , byteNum);
ShowMsg(socketSend.RemoteEndPoint.ToString() + ":" + str);
}
catch { }
}
}
private void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
} private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
} private void btnSend_Click(object sender, EventArgs e)
{
string str = txtMsg.Text;
List<byte> list = new List<byte>();
list.Add();
byte[] buffer = Encoding.UTF8.GetBytes(str);
list.AddRange(buffer);
byte[] newBuffer = list.ToArray();
string ip = cboUsers.SelectedItem.ToString();
socketClientList[ip].Send(newBuffer);
} private void btnSelectFile_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = @"D:\";
ofd.Title = "请选择要发送的文件";
ofd.Filter = "所有文件|*.*";
ofd.ShowDialog();
txtFilePath.Text = ofd.FileName;
} private void btnSendFile_Click(object sender, EventArgs e)
{
string path = txtFilePath.Text;
using(FileStream fsRead = new FileStream(path, FileMode.Open, FileAccess.Read))
{
try
{
byte[] buffer = new byte[ * * ];
int l = fsRead.Read(buffer, , buffer.Length);
List<byte> list = new List<byte>();
list.Add();
list.AddRange(buffer);
byte[] newBuffer = list.ToArray();
socketClientList[cboUsers.SelectedItem.ToString()].Send(newBuffer,,l+,SocketFlags.None);
}
catch { }
}
} private void btnShake_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[];
buffer[] = ;
socketClientList[cboUsers.SelectedItem.ToString()].Send(buffer);
}
}
}
客户端代码如下:
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 ClientRevier
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false;
}
private Socket socketClient;
private void btnStart_Click(object sender, EventArgs e)
{
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(txtServer.Text);
IPEndPoint iep = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text));
socketClient.Connect(iep);
ShowMsg("连接成功");
//因为要不停接受消息,所以用while循环,并且为了接受消息的同时能做其他事,把这个放到线程中执行
Thread thread = new Thread(ClientRecieve);
thread.IsBackground = true;
thread.Start();
}
private void ClientRecieve()
{
while (true)
{
byte[] buffer = new byte[ * * ];
int byteNum = socketClient.Receive(buffer);
if (byteNum == )
{
break;
}
switch (buffer[])
{
case :
string str = Encoding.UTF8.GetString(buffer, , byteNum-);
ShowMsg(socketClient.RemoteEndPoint + ":" + str);
break;
case :
SaveFileDialog sfd = new SaveFileDialog();
sfd.InitialDirectory = @"D\";
sfd.Title = "请选择需要保存的路径";
sfd.Filter = "文本文件|*.txt|图片文件|*.jpg|所有文件|*.*";
sfd.ShowDialog(this);
using(FileStream fsWrite = new FileStream(sfd.FileName, FileMode.OpenOrCreate, FileAccess.Write))
{
fsWrite.Write(buffer, , byteNum - );
MessageBox.Show("保存成功");
}
break;
case :
for(int i = ; i < ; i++)
{
this.Location = new Point(, );
this.Location = new Point(, );
}
break;
default:break;
} }
}
private void ShowMsg(string str)
{
txtLog.AppendText(str + "\r\n");
} private void btnSend_Click(object sender, EventArgs e)
{
string str = txtMsg.Text;
byte[] buffer = Encoding.UTF8.GetBytes(str);
socketClient.Send(buffer); }
}
}
C# Socket 编程 Sample的更多相关文章
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
- java socket编程(li)
一.网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以 ...
- Python Socket 编程——聊天室示例程序
上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...
- Linux下的C Socket编程 -- server端的简单示例
Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...
- Linux下的C Socket编程 -- 获取对方IP地址
Linux下的C Socket编程(二) 获取域名对应的IP地址 经过上面的讨论,如果我们想要连接到远程的服务器,我们需要知道对方的IP地址,系统函数gethostbyname便能够实现这个目的.它能 ...
- Linux下的C Socket编程 -- 简介与client端的处理
Linux下的C Socket编程(一) 介绍 Socket是进程间通信的方式之一,是进程间的通信.这里说的进程并不一定是在同一台机器上也有可能是通过网络连接的不同机器上.只要他们之间建立起了sock ...
- python网络编程-socket编程
一.服务端和客户端 BS架构 (腾讯通软件:server+client) CS架构 (web网站) C/S架构与socket的关系: 我们学习socket就是为了完成C/S架构的开发 二.OSI七层 ...
- Socket编程实践(2) Socket API 与 简单例程
在本篇文章中,先介绍一下Socket编程的一些API,然后利用这些API实现一个客户端-服务器模型的一个简单通信例程.该例子中,服务器接收到客户端的信息后,将信息重新发送给客户端. socket()函 ...
- Socket编程实践(1) 基本概念
1. 什么是socket socket可以看成是用户进程与内核网络协议栈的编程接口.TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间.用户空间的程序需要通 ...
随机推荐
- vue—生命周期的基本介绍
Vue生命周期: 什么是生命周期: Vue 实例从创建到销毁的过程,就是生命周期.也就是从开始创建.初始化数据.编译模板.挂载Dom→渲染.更新→渲染.卸载等一系列过程,我们称这是 Vue 的生命周期 ...
- 利用ant-design封装react的地址输入组件
在上一节利用element-ui封装地址输入的组件留下了个尾巴,说react搭配ant-design封装一下地址输入的组件的.本来应该早早就完成的,但是由于这中间发生了一些事情,导致了突发性的换了工作 ...
- hdu 2767 强连通缩点处理加边问题
#include <cstring> #include <cstdlib> #include <cstdio> 缩点的好处就是可以将乱七八糟的有向图 转化为无环的有 ...
- MySQL设置自增字段
1.MySQL每张表只能有1个自增字段,这个自增字段即可作为主键,也可用作非主键使用,但是请注意将自增字段当做非主键使用时必须为其添加唯一索引,否则系统将会报错 )将自动增长字段设置为主键 CREAT ...
- CF336C-Vasily the Bear and Sequence题解--贪心
题目链接 https://www.luogu.org/problemnew/show/CF336C 分析 一个比较妙的贪心 我们要让最后\(and\)起来的数被\(2^k\)整除且\(k\)最大,我们 ...
- pthread 编程基础
Linux系统下的多线程遵循POSIX线程接口,称为pthread.编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a.与vxworks上任务的概 ...
- Linux I2C核心、总线和设备驱动
目录 更新记录 一.Linux I2C 体系结构 1.1 Linux I2C 体系结构的组成部分 1.2 内核源码文件 1.3 重要的数据结构 二.Linux I2C 核心 2.1 流程 2.2 主要 ...
- jQuery获取的dom对象和原生的dom对象有何区别
js原生获取的dom是一个对象,jQuery对象就是一个数组对象,其实就是选择出来的元素的数组集合,所以说他们两者是不同的对象类型不等价 原生DOM对象转jQuery对象 var box = docu ...
- Flutter 34: 图解自定义 View 之 Canvas (一)
小菜最近在学习自定义 View,刚了解了一下 Paint 画笔的神奇之处,现在学习一下 Canvas 画布的神秘之处.Flutter 提供了众多的绘制方法,小菜接触不深,尽量都尝试一下. Canvas ...
- 【Distributed】互联网安全架构
一.常见Web安全漏洞 1.1 XSS攻击 什么是XSS攻击手段 如何防御XSS攻击 1.2 SQL注入攻击 什么是SQL注入 SQL注入防攻击手段 MyBatis #与$区别 1.3 Http请求防 ...