一.实现客户端简要步骤
第一步:调用socket()函数创建一个用于通信的套接字
第二步:通过设置套接字地址结构,说明客户端与之通信的服务器的IP地址和端口号
第三步:调用connect()函数来建立与服务器的连接
第四步:调用读写函数发送或者接收数据
第五步:终止连接
二.客户端主体部分代码贴
//第一步:调用Socket()函数创建套接字
socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//第二步:设置套接字地址结构,提供客户端与之通信的服务器的IP地址和端口号
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(this.txt_IP.Text.Trim()), int.Parse(this.txt_Port.Text.Trim()));
//第三步:调用connect()函数建立与服务器的连接
try
{
socketClient.Connect(ipe);
}
catch (Exception ex)
{
AddLog(2, "连接服务器失败" + ex.Message);
return;
}
//连接成功后创建多线程接收数据
Task.Run(new Action(() =>
{
CheckReceiveMsg();
}));
AddLog(0, "成功连接服务器");
this.btn_Connect.Enabled = false;
}
// 第四步:调用读写函数发送/接收数据方法
private void CheckReceiveMsg()
{
while (true)
{
//缓冲区
byte[] buffer = new byte[1024 * 1024 * 10];
int length = -1;
try
{
length = socketClient.Receive(buffer);
}
catch (Exception)
{
AddLog(2, "服务器断开连接");
break;
}
if (length>0)
{
string msg = Encoding.Default.GetString(buffer, 0, length);//将字节数组中的字节序列一 一解码为字符串
AddLog(0, "接收自服务器:" + msg);
}
else
{
break;
}
}
}
// 第五步:断开连接
socketClient?.Close();
三.文件传送与接收代码贴
文件传送步骤注意:这里有一个解码编码的过程,要记得一切皆字节,比如客户端向服务器传送文件,从磁盘里面选中文件后首先需要在客户端这里将文件解码为字节序列,然后一一发送。同样服务器接收时接收的为字节序列,在指定存储地址写入文件时又有一个编码的过程。
以下为部分代码贴:
客户端Send:
①:首先需要在磁盘选择文件,这里使用OpenFileDialog组件
OpenFileDialog ofd = new OpenFileDialog();
//设置桌面路径
ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
if (ofd.ShowDialog()==DialogResult.OK)
{
this.txt_File.Text = ofd.FileName;
}
②:解码文件并发送
1.先获取文件全名称
using (FileStream fs = new FileStream(this.txt_File.Text, FileMode.Open))
{
//获取该文件名称
string filename = Path.GetFileName(this.txt_File.Text);
//获取该文件后缀名
string fileExtension = Path.GetExtension(this.txt_File.Text);
string strMsg = "发送文件:" + filename + "." + fileExtension;
byte[] send1 = Encoding.UTF8.GetBytes(strMsg);//将文件全名称使用UTF8编码为字节数组
byte[] send1msg = new byte[send1.Length + 1];
Array.Copy(send1, 0, send1msg, 1, send1.Length);
send1msg[0] = (byte)MessageType.UTF8;//加入消息类型
socketClient?.Send(send1msg);
2.文件内容
byte[] send2 = new byte[1024 * 1024 * 10];//指定传输的字节序列大小,
int length = fs.Read(send2, 0, send2.Length);//文件解码
byte[] send2Msg = new byte[length + 1];
Array.Copy(send2, 0, send2Msg, 1, length);
send2Msg[0] = (byte)MessageType.File;
socketClient?.Send(send2Msg);//发送
服务端接收:
Invoke(new Action(() => //跨线程使用invoke委托执行
{
SaveFileDialog sfd = new SaveFileDialog();//另存为组件
sfd.Filter = "txt files(*.txt)|*.txt|xls files(*.xls)|*.xls|xlsx files(*.xlsx)|*.xlsx|All files(*.*)|*.*";//预定另存的文件类型
if (sfd.ShowDialog() == DialogResult.OK)
{
string fileSavePath = sfd.FileName;//获取文件名
using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))//在指定路径另存文件
{
fs.Write(buffer, 1, length - 1);//编码写入文件
}
}
}));
四.演示
将磁盘内一个图片通过客户端发送至服务器,另存为picture1.jpg