小白最近在做一个项目,涉及到Android端和Window端进行数据传输,实现通信过程中即时传输,即时回复的功能,所以用到了Socket异步通信。
Socket通信的基础是通信的双方都在同一个局域网内,为此小白让电脑端开WIFI,然后Android端连接创建通信环境。
1、C#端
1.1MyFriend.cs
设置缓存byte数组,接收java传输的数据。
class MyFriend
{
//用于保存与每个客户相关信息:套接字与接收缓存
public Socket socket;
public byte[] Rcvbuffer;
//实例化方法
public MyFriend(Socket s)
{
socket = s;
}
//清空接受缓存,在每一次新的接收之前都要调用该方法
public void ClearBuffer()
{
Rcvbuffer = new byte[1024];
}
//
public void Dispose()
{
try
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
finally
{
socket = null;
Rcvbuffer = null;
}
}
}
1.2 主程序
bool IsStart = false;//检测socket线程是否开启
TcpListener listener; //建立线程监听
int Port = 10803;
MyFriend friend = null;
string data; //接收到的数据
基础操作,把一些该定义的定义了,
public int GetAvailablePort()
{
Random r = new Random();
int port = r.Next(1024, 65535);
while (PortInUse(port) == true)
{
port = r.Next(1024, 65535);
}
return port;
}
//判断端口是否被用
public static bool PortInUse(int port)
{
bool inUse = false;
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();
foreach (IPEndPoint endPoint in ipEndPoints)
{
if (endPoint.Port == port)
{
inUse = true;
break;
}
}
return inUse;
}
这里把通信IP,Port搞定。
private void start_listen_Click(object sender, EventArgs e)
{
//获取本机IPv4地址
IPAddress ip = IPAddress.Parse(GetLocalAddresses());
//设置默认端口号
int Port = GetAvailablePort();
//服务器已在其中监听,则返回
if (IsStart)
return;
//服务器启动侦听
IPEndPoint localep = new IPEndPoint(ip, Port);
listener = new TcpListener(localep);
listener.Start();
IsStart = true;
listBox_ShowMessage.Invoke(AppendString, string.Format("服务器已经启动监听!端点为:{0}。", listener.LocalEndpoint.ToString()));
listBox_ShowMessage.Invoke(AppendString, DateTime.Now.ToString());
listBox_ShowMessage.Invoke(AppendString, "---------------------------------------");
//接受连接请求的异步调用
AsyncCallback callback = new AsyncCallback(AcceptCallBack);
listener.BeginAcceptSocket(callback, listener);
}
listBox_ShowMessage 是windows窗体程序listbox空间,显示相关的信息。
private void AcceptCallBack(IAsyncResult ar)
{
try
{
//完成异步接收连接请求的异步调用
//将连接信息添加到列表和下拉列表中
Socket handle = listener.EndAcceptSocket(ar);
MyFriend frd = new MyFriend(handle);
AsyncCallback callback;
//继续调用异步方法接收连接请求
if (IsStart)
{
callback = new AsyncCallback(AcceptCallBack);
listener.BeginAcceptSocket(callback, listener);
}
//开始在连接上进行异步的数据接收
frd.ClearBuffer();
callback = new AsyncCallback(ReceiveCallback);
frd.socket.BeginReceive(frd.Rcvbuffer, 0, frd.Rcvbuffer.Length, SocketFlags.None, callback, frd);
}
catch
{
//在调用EndAcceptSocket方法时可能引发异常
//套接字Listener被关闭,则设置为未启动侦听状态
IsStart = false;
}
}
private void ReceiveCallback(IAsyncResult ar)
{
MyFriend frd = (MyFriend)ar.AsyncState;
try
{
int i = frd.socket.EndReceive(ar);
data = Encoding.UTF8.GetString(frd.Rcvbuffer, 0, i);
int receiveNumber = frd.socket.Receive(frd.Rcvbuffer);
//SocketMassage是接收的结构体,用来拆解byte数组,可以根据自己定义的来处理
SocketMassage rcv_socmsg = new SocketMassage();
if (rcv_socmsg.msgType == "*1*")
{
拆byte数组头,
}
else if (rcv_socmsg.msgType == "*2*")
{
byte[] sendBuffer = send_msg.getCombine();
SendData(frd, sendBuffer);
}
else if (rcv_socmsg.msgType == "*3*")
{
}
else if (rcv_socmsg.msgType == "*4*")
{
}
frd.ClearBuffer();
AsyncCallback callback = new AsyncCallback(ReceiveCallback);
frd.socket.BeginReceive(frd.Rcvbuffer, 0, frd.Rcvbuffer.Length, SocketFlags.None, callback, frd);
}
catch
{
}
}
private void SendCallback(IAsyncResult ar)
{
MyFriend frd = (MyFriend)ar.AsyncState;
try
{
frd.socket.EndSend(ar);
}
catch
{
}
}
private void SendData(MyFriend frd, byte[] data)
{
try
{
AsyncCallback callback = new AsyncCallback(SendCallback);
frd.socket.BeginSend(data, 0, data.Length, SocketFlags.None, callback, frd);
}
catch
{
}
}