c#
- 写在前面:前俩天学了c#的Socket搭建TCP网络通信,反手和坐在背后的彬彬hxd萌生了连一手通讯的想法,于是他java,我c#开始了操作,第一天我们一个c#,一个java成功一对一局域网通信连上了,第二天,想升个级,做一个服务端,做一堆客户端,客户端连接上服务端后可以给其他客户端发送消息。
于是说干就干,第二天我做了简易的服务端和客户端,勉强可以多个客户端互相通话了,好了我的故事就此打住了,但彬彬没有完,现在是第三天,他把项目写的更完备,部署到了自己的服务器上,拿到他的程序和服务器ip,就可以登入这家伙的小型通话软件。虽然没什么实际作用,不过姑且算是给刚入手Socket编程的我练了练手,于是记录一些操作。
c#编写Socket之服务端
static Socket serverSocket;
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("192.168.43.109");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8000);
serverSocket.Bind(ipEndPoint);
- 让一个绑定了ip和端口号的Socket作为服务器端来监听接收客户端的连接
serverSocket.Listen(1);
Socket clientSocket = serverSocket.Accept();
- 当接受了一个客户端的连接后,使用该客户端的Socket的BeginReceive方法来接受其发来的消息
static byte[] dataBuffer = new byte[1024];
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
- 接收消息用的回调函数,这个函数有个固定的IAsyncResult参数,别问问就固定。
这个函数中调用的 ar.AsyncState as Socket;这句话是调用IAsyncResult参数的AsyncState方法,来取得之前BenginReceive方法的第六个参数,由于当时我传的客户端socket所以这边直接将其转换为Socket型的对象,存下来,就是客户端的Socket
这个函数用了clientSocket.EndReceive(IasyncResult a);方法,调用客户端socket的这个方法,并把这条线程对应的IAsyncResult参数传进去可以取得这条线程的返回值,这里的返回值是接收到的这条数据的字节数,可以用来翻译字节数据。
另外我写了字符串数据翻译的格式是:以’$'开头,那么这条消息是给当前客户端改名,以其他数据开头,中间用 ‘ $’隔开后面再接一条数据,意味着给某人发某消息,符号前是人的名字,符号后是消息
方法实现如下
void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);
if(msg[0]=='$')
{
Console.WriteLine("客户端{0}更名为:{1}", this.Name, msg.Substring(1));
Name = msg.Substring(1);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
return;
}
string name = "";
for(int i = 0;i<msg.Length;i++)
{
if(msg[i]=='$')
{
name = msg.Substring(0, i);
msg = msg.Substring(i + 1);
break;
}
}
if(name=="")
{
GoMsg("连个消息都不会发,打车滚吧,傻逼");
}
else
{
Program.GoMsg(name, msg, this);
}
Console.WriteLine("从客户端{0}接收到数据:" + msg,this.Name);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
- 除了接收消息,服务器还要把客户端的消息转发给对应的客户端
public void GoMsg(string msg)
{
clientSocket.Send(Encoding.UTF8.GetBytes(msg));
}
static public void GoMsg(string name,string msg,Client cl)
{
int i = 0;
for (;i< ClientNum;i++)
{
if(Client[i].Name==name)
{
break;
}
}
if(i == ClientNum)
{
cl.GoMsg("没这个人,你发你马呢");
}
else
{
msg = cl.Name +"对你说:"+ msg;
Client[i].GoMsg(msg);
}
}
c#编写Socket之客户端
- 首先我们得有一个Socket对象,绑定好服务器的ip和端口,去连接它,方法和服务器那边差的不多,就是多用了一个连接方法Connect(IPEndPoint i),这个Socket对象里的方法是与参数i绑定的ip和端口所指的服务器做连接,代码如下
Console.WriteLine("请输入目标服务器的端口");
ip = Console.ReadLine();
dk = int.Parse(ip);
Console.WriteLine("请输入目标服务器的ip");
ip = Console.ReadLine();
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), dk));
- 接收服务器发来的消息,方法与服务器那边接受客户端的消息差不多,不过更简单,由于服务器已经对消息进行了解析,整合,所以这边什么都不需要做,直接接受,翻译,打印即可
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
static byte[] dataBuffer = new byte[1024];
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);
Console.WriteLine(msg);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
- 客户端给服务器发消息就粗暴了很多,直接在主线程一手死循环,无限发就行(没有跳出,没有断开连接,别学(装傻))
while (true)
{
string s = Console.ReadLine();
clientSocket.Send(Encoding.UTF8.GetBytes(s));
}
c#编写Socket总源码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using System.Threading;
namespace 与彬彬的Socket
{
class Program
{
static Socket serverSocket;
static Client[] Client = new Client[100];
static int ClientNum = 0;
static void Main(string[] args)
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAddress = IPAddress.Parse("192.168.43.109");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 8000);
serverSocket.Bind(ipEndPoint);
AddClientSocket();
}
static public void AddClientSocket()
{
Client s = new Client("用户"+ClientNum, serverSocket);
Client[ClientNum] = s;
Thread th = new Thread(s.Socket_Client);
th.Start();
ClientNum++;
}
static public void GoMsg(string name,string msg,Client cl)
{
int i = 0;
for (;i< ClientNum;i++)
{
if(Client[i].Name==name)
{
break;
}
}
if(i == ClientNum)
{
cl.GoMsg("没这个人,你发你马呢");
}
else
{
msg = cl.Name +"对你说:"+ msg;
Client[i].GoMsg(msg);
}
}
static byte[] dataBuffer = new byte[1024];
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);
Console.WriteLine("从客户端接收到数据:" + msg);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
namespace 与彬彬的Socket
{
class Client
{
Socket serverSocket;
Socket clientSocket;
public string Name = "";
public Client(string name, Socket serverSocket)
{
Name = name;
this.serverSocket = serverSocket;
}
public void GoMsg(string msg)
{
clientSocket.Send(Encoding.UTF8.GetBytes(msg));
}
public void Socket_Client()
{
StartServerAsync(serverSocket);
}
private void StartServerAsync(Socket serverSocket)
{
serverSocket.Listen(1);
Socket clientSocket = serverSocket.Accept();
this.clientSocket = clientSocket;
GoMsg("你好,你是:" + Name);
Program.AddClientSocket();
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
byte[] dataBuffer = new byte[1024];
void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);
if(msg[0]=='$')
{
Console.WriteLine("客户端{0}更名为:{1}", this.Name, msg.Substring(1));
Name = msg.Substring(1);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
return;
}
string name = "";
for(int i = 0;i<msg.Length;i++)
{
if(msg[i]=='$')
{
name = msg.Substring(0, i);
msg = msg.Substring(i + 1);
break;
}
}
if(name=="")
{
GoMsg("连个消息都不会发,打车滚吧,傻逼");
}
else
{
Program.GoMsg(name, msg, this);
}
Console.WriteLine("从客户端{0}接收到数据:" + msg,this.Name);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using System.Threading;
namespace 与彬彬的Socket客户端
{
class Program
{
static string ip;
static int dk;
static void Main(string[] args)
{
Console.WriteLine("请输入目标服务器的端口");
ip = Console.ReadLine();
dk = int.Parse(ip);
Console.WriteLine("请输入目标服务器的ip");
ip = Console.ReadLine();
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), dk));
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
while (true)
{
string s = Console.ReadLine();
clientSocket.Send(Encoding.UTF8.GetBytes(s));
}
}
static byte[] dataBuffer = new byte[1024];
static void ReceiveCallBack(IAsyncResult ar)
{
Socket clientSocket = ar.AsyncState as Socket;
int count = clientSocket.EndReceive(ar);
string msg = Encoding.UTF8.GetString(dataBuffer, 0, count);
Console.WriteLine(msg);
clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
}
}
}
- 如此这般 结束(三个源码分俩个项目生成后就可以在局域网用辣!)