我想使用TCP Python socket
模块发送/接收'已分配的'数据。
我的接收服务器端socket
设置为在单个recv
呼叫中接收40个字节的数据:
while True:
data = connection.recv(40)
if not data:
break
...
connection.close()
我有一些〜500字节长的样本数据,转换为bytes
对象,由'客户'发送到'服务器':
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
...
s.send(sample_data)
虽然我只有一次调用send
方法,但这意味着客户端一次发送40个字节的'sample_data',而服务器'一次请求'40个字节,只要整个包没有完全发送?
我在this post中找到SO_SNDBUF
参数设置send
socket
缓冲区的大小,但它与'普通'socket
有何不同之处SO_SNDBUF
正在设定?
buffer_size = 40
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size)
...
s.send(sample_data)
答案 0 :(得分:2)
TCP是一种流协议,意味着没有消息边界。它只是一个字节流。把它想象成一个FIFO。如果客户端发送500个字节,那么在服务器上将接收500个总字节。 recv(40)
将按发送顺序从1-40个字节收到。您必须检查返回值以查看您收到了多少。
您可以收到数据长度:40,40,40,40,40,40,40,40,40,40,40,40,20
或者你可以得到类似的东西:40,40,5,40,40,40,40,40,40,40,40,40,40,15
在阻塞套接字上创建另一个recv
将挂起,直到收到至少一个字节,或者如果客户端关闭套接字则返回零字节。
由服务器将数据连接在一起并确定是否接收到完整的数据传输。通常,您需要定义协议以确定完整消息的含义。这可能是&#34; 500字节是一个完整的消息&#34;。您还需要处理发送两条消息并且单个 <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString='<%$ ConnectionStrings:ShiftScheduleConnectionString %>' DeleteCommand="DELETE FROM [Example] WHERE [ID] = @ID" InsertCommand="INSERT INTO [Example] ([AssociateName], [Login], [Logout], [Home_Login], [Home_Logout]) VALUES (@AssociateName, @Login, @Logout, @Home_Login, @Home_Logout)" SelectCommand="SELECT * FROM [Example]" UpdateCommand="UPDATE [Example] SET [AssociateName] = @AssociateName, [Login] = @Login, [Logout] = @Logout, [Home_Login] = @Home_Login, [Home_Logout] = @Home_Logout WHERE [ID] = @ID">
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="AssociateName" Type="String"></asp:Parameter>
<asp:Parameter Name="Login" Type="String"></asp:Parameter>
<asp:Parameter Name="Logout" Type="String"></asp:Parameter>
<asp:Parameter Name="Home_Login" Type="String"></asp:Parameter>
<asp:Parameter Name="Home_Logout" Type="String"></asp:Parameter>
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="AssociateName" Type="String"></asp:Parameter>
<asp:Parameter Name="Login" Type="String"></asp:Parameter>
<asp:Parameter Name="Logout" Type="String"></asp:Parameter>
<asp:Parameter Name="Home_Login" Type="String"></asp:Parameter>
<asp:Parameter Name="Home_Logout" Type="String"></asp:Parameter>
<asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
</UpdateParameters>
</asp:SqlDataSource>
<asp:GridView ID="GridView1" OnRowUpdating="GridView1_RowUpdating" OnRowDataBound="GridView1_RowDataBound" OnRowEditing="GridView1_RowEditing" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True"></asp:CommandField>
<asp:BoundField DataField="ID" HeaderText="ID" ReadOnly="True" InsertVisible="False" SortExpression="ID"></asp:BoundField>
<asp:BoundField DataField="AssociateName" HeaderText="AssociateName" SortExpression="AssociateName"></asp:BoundField>
<asp:BoundField DataField="Login" HeaderText="Login" SortExpression="Login"></asp:BoundField>
<asp:BoundField DataField="Logout" HeaderText="Logout" SortExpression="Logout"></asp:BoundField>
<asp:BoundField DataField="Home_Login" HeaderText="Home_Login" SortExpression="Home_Login"></asp:BoundField>
<asp:BoundField DataField="Home_Logout" HeaderText="Home_Logout" SortExpression="Home_Logout"></asp:BoundField>
</Columns>
</asp:GridView>
可以从一条消息的结尾和另一条消息的开头获取数据的情况。
通常不需要使用套接字选项调整缓冲区大小。