美文网首页
Socket 小知识

Socket 小知识

作者: 四月白绵羊 | 来源:发表于2017-04-01 00:56 被阅读0次

之前想要写一个简洁的小型服务器,包括 ServerClient,所以用到了 Pythonsocket 模块。
这里先附上 两段代码

  1. Server
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket  

print 'Start listening...'

HOST='129.173.67.53'
# PORT=52631
# HOST='localhost'
PORT=3306
print("IP Addr : " + HOST , " , PORT : " + str(PORT))

s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)   
// 绑定 IP 和 端口
s.bind((HOST,PORT))   
s.listen(1)         
while 1:
    conn,addr=s.accept()   
    print 'Connected by ', addr   
    
    text1 = conn.recv(1024)
    print "Text 1 :" + text1
    text2 = conn.recv(1024)

    # print "Text 1 : " + text1
    print "Text 2 : " + text2


    result = str(gtmapi.textSimilarity(text1 , text2))
    conn.sendall(result)
    print "Sim : " + result

    conn.close()
jpype.shutdownJVM()

  1. Client
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket  

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = ('localhost', 8001)
#server_address = ('129.173.67.53', 3306)
print 'connecting to'
print server_address
sock.connect(server_address)
while 1:

    text1 = "Im sitong"
    text2 = "I am no sitong"

    sock.sendall(text1)
    sock.sendall(text2)

    result = sock.recv(1024)
    print "Sim : " + result

    sock.close()
    break

讨论

运行了上面的代码之后,你会发现个是有问题的,问题就是 你 recv 获取的两个text 的内容可能是错误的。例如

// sent texts
text1 = "I am apple."
text2 = "I like apple."
// recv texts
text1 = "I am"
text2 = apple. I like apple.

就是因为 sendall 发送的信息给 client之后, 并不能保证 client 一次性全部都收到。而且使用的 sendall 的次数和 recv 的次数是没有关系的。也就是说, 并不是你连续使用两次sendall, 就可以使用 两个 recv 来分别接收两次发送的数据。
解决的办法有三个:

  • 基础的接收方法
    因为当与服务器的socket 断开之后,client 会接受到空字符串,所以可以直接加上循环接收数据,当收到空字符串的时候就是结束了。代码如下:
import socket,struct,sys,time

Port=22220
#assume a socket disconnect (data returned is empty string) means  all data was #done being sent.
def recv_basic(the_socket):
    total_data=[]
    while True:
        data = the_socket.recv(20480)    
        if not data: break
        total_data.append(data)
    return ''.join(total_data)
  • 尾部标记法
    就是设置好一个约定,当接收到的数据结尾包含某个字符串的时候,就代表数据传输结束了。
    代码如下:
End='something useable as an end marker'
def recv_end(the_socket):
    total_data=[];data=''
    while True:
            data=the_socket.recv(8192)
            if End in data:
                total_data.append(data[:data.find(End)])
                break
            total_data.append(data)
            if len(total_data)>1:
                #check if end_of_data was split
                last_pair=total_data[-2]+total_data[-1]
                if End in last_pair:
                    total_data[-2]=last_pair[:last_pair.find(End)]
                    total_data.pop()
                    break
    return ''.join(total_data)
  • 负载长度方法
    就是在数据传输一开始 写明要传输的数据的长度。这要求接收方一边接收数据,一遍解析数据。
    代码如下:
def recv_size(the_socket):
    #data length is packed into 4 bytes
    total_len=0;total_data=[];size=sys.maxint
    size_data=sock_data='';recv_size=8192
    while total_len<size:
        sock_data=the_socket.recv(recv_size)
        if not total_data:
            if len(sock_data)>4:
                size_data+=sock_data
                size=struct.unpack('>i', size_data[:4])[0]
                recv_size=size
                if recv_size>524288:recv_size=524288
                total_data.append(size_data[4:])
            else:
                size_data+=sock_data
        else:
            total_data.append(sock_data)
        total_len=sum([len(i) for i in total_data ])
    return ''.join(total_data)

相关文章

  • Socket 小知识

    之前想要写一个简洁的小型服务器,包括 Server 和 Client,所以用到了 Python 的 socket ...

  • 0. Socket学习资料汇总

    Socket理论知识 iOS Socket理论知识 关于iOS socket都在这里了 iOS Socket T...

  • #Socket回顾学习笔记

    Socket学习笔记 Socket基础知识 背景 Socket概念 Socket 又称"套接字",是系统提供的用于...

  • Socket 知识点总结复习

    Socket 知识总结 1.socket 概念 通讯流程: 2.socket 断开重连 socket 的KeepA...

  • 1. iOS Socket 学习笔记

    一. Socket 基础知识 Socket 的位置首先上一张图, 让你知道 Socket 的位置。socket 什...

  • TCP

    基础知识 Linux命令 查看server socket netstat -ltnp 查看socket netst...

  • iOS#GCDAsyncSocket使用

    背景 最近在开发使用Socket,重新复习了socket基本知识,文章如下: #Socket回顾学习笔记UDP G...

  • 【tcp】网络分析好文

    socket 编程基础知识https://cizixs.com/2015/03/29/basic-socket-p...

  • iOS socket知识

    1.什么是socket socket又称为套接字,网络上的两个程序通过一个双向的通信连接实现数据交换,这个连接的一...

  • Socket相关知识

    Socket Socket又称"套接字” 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为...

网友评论

      本文标题:Socket 小知识

      本文链接:https://www.haomeiwen.com/subject/udbbottx.html