同步socket, 异步socket, 多线程socket, 多进程socket

同步socket, 异步socket, 多线程socket, 多进程socket,第1张

socket常用,本文立足同步和异步socket,以及现有的socketserver库。

同步socket一般有利用socket库直接,就可以写出tcp或udp的套接

socketserver提供的线程或进程方式的socket

利用python 3.5+的asyncio协议,封装一个协程的socket server ,普通的socket客户也可以连接。

服务器端

客户端

为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据

构造报头信息

服务端

客户端

粘包,分包都tcp

tcp为什么会有粘包分包这些情况:

1.服务端处理不过来

2.客户端采用优化纳格尔算法,达到一定字节才发

怎么处理:

1. 客,服双方确定包头规范,根据包头的信息取包长度

2. 客户端发送带上标记位,如\n, 服务端根据标记取包

服务器端

客户端

服务器端

客户端

服务器端

客户端

封装了socket,而且解决了Io阻塞问题

服务端

客户端

客户端

参考:

http://www.cnblogs.com/jokerbj/p/7422349.html

http://xiaorui.cc/2016/03/08/%E8%A7%A3%E5%86%B3golang%E5%BC%80%E5%8F%91socket%E6%9C%8D%E5%8A%A1%E6%97%B6%E7%B2%98%E5%8C%85%E5%8D%8A%E5%8C%85bug/

http://xiaorui.cc/2016/04/15/%E6%89%93%E9%80%A0mvc%E6%A1%86%E6%9E%B6%E4%B9%8Bsocket%E8%8E%B7%E5%8F%96http%E7%B2%98%E5%8C%85%E9%97%AE%E9%A2%98/

https://www.jianshu.com/p/065c53cab328

https://mozillazg.com/2017/08/python-asyncio-note-io-protocol.html#hidid3

我以前写过类似的socket通信,虽然你用的方法和我的不太一样,但我还是感觉有一些问题

接受消息的时候,你用的是while(true)循环,当第一次将消息接受后,缓冲区就为空了,我想你再用循环去接收应该会出问题。

我记得有个poll方法,具体什么用途忘记了(很久没写代码了)你在循环里面加个if (clientsocket.Poll(1000, SelectMode.SelectRead))判断语句“clientsocket为你需要接收消息的socket”看看能不能解决,或者就用异步也可以,我可以发一下我以前的代码你参考下:

using System

using System.Collections.Generic

using System.ComponentModel

using System.Data

using System.Drawing

using System.Text

using System.Windows.Forms

using System.Net

using System.Net.Sockets

using System.Threading

namespace test4_2

{

public partial class Form1 : Form

{

Socket connectSocket

//Socket client

byte[] bytes = new byte[1024]

delegate void listboxDel(string s)

listboxDel listboxdel

public Form1()

{

InitializeComponent()

textBoxContent.Focus()

listboxdel = new listboxDel(listbox)

//为连接指派线程

Thread threadConnect = new Thread(new ThreadStart(Connect))

threadConnect.Start()

}

public void listbox(string str)

{

listBox1.Items.Add(str)

listBox1.SelectedIndex = listBox1.Items.Count - 1

listBox1.ClearSelected()

}

//连接方法

public void Connect()

{

try

{

//建立连接socket

connectSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp)

//开始异步连接

connectSocket.BeginConnect(IPAddress.Parse("172.16.94.152"),

82,

new AsyncCallback(ConnectCallback), //定义回调函数代理

connectSocket) //传递给回调函数的状态

}

catch (Exception e)

{

MessageBox.Show(e.Message)

}

}

//连接方法的回调函数

private void ConnectCallback(IAsyncResult ar)

{

try

{

//从传递的状态中获取套接字,创建一个客户端套接字

Socket client = (Socket)ar.AsyncState

//完成挂起的连接操作

client.EndConnect(ar)

listBox1.Invoke(listboxdel, "连接服务器成功,可以开始通话!")

client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client)

}

catch (Exception e)

{

Console.WriteLine(e.ToString())

}

}

public void receivecallback(IAsyncResult ar)

{

try

{

Socket client = (Socket)ar.AsyncState

int length = client.EndReceive(ar)

listBox1.Invoke(listboxdel, Encoding.UTF8.GetString(bytes, 0, length))

client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client)

}

catch

{

}

}

//发送方法

private void Send(String data)

{

//使用ASCII转换字符串为字节序列

byte[] byteData = Encoding.UTF8.GetBytes(data) //将字符串转换成字节序列

//开始向远端设备发送数据

connectSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,

new AsyncCallback(SendCallback), connectSocket)

}

//发送方法的回调函数

private void SendCallback(IAsyncResult ar)

{

try

{

//从传递的状态中获取套接字,创建一个客户端套接字

Socket client = (Socket)ar.AsyncState

//结束异步数据传输操作,返回传输的字节数

int bytesSent = client.EndSend(ar)

listBox1.Invoke(listboxdel, textBoxUser.Text +":"+ textBoxContent.Text)

}

catch (Exception e)

{

MessageBox.Show(e.ToString())

}

}

private void buttonSend_Click(object sender, EventArgs e)

{

Send(textBoxUser.Text+":"+textBoxContent.Text)

}

}

}


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/205878.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-03
下一篇2023-04-03

发表评论

登录后才能评论

评论列表(0条)

    保存