Python套接字中的一个recv接收两个或多个send的内容

3
这是一个简单的套接字程序,包括一个服务器和一些客户端。客户端使用简单的RSA加密算法对其文本进行加密,然后服务器解密句子并将解密后的句子发送回客户端。
服务器:
import socket
import sys
from thread import *
from math import *
from random import *
import random
HOST = ''   
PORT = 8888
size=2**16
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

#Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

#Start listening on socket
s.listen(10)
print 'Socket now listening'

def decoder(codedString,d,n):
    breakcoded=[]
    coded=(codedString)
    #print coded;
    for i in range (len(coded)):
            breakcoded.append(chr(((int(coded[i])**d) % n)+48))
    stri= ""
    for i in range (len(breakcoded)):
            stri+=breakcoded[i]
    return stri

#Function for handling connections. This will be used to create threads
def clientthread(conn):
    #Sending message to connected client
    conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
    #infinite loop so that function do not terminate and thread do not end.
    while True:    
    #Receiving from client
        data = conn.recv(1024)
##        data=s.recv(size)
    l = int (data)
    #print l
    coded=[]
    i=0
    data1=conn.recv(size)
print 'Recieved n: ',data1
n = int (data1)
data2=conn.recv(size)
print 'Recieved d: ',data2
d = int (data2)
for i in range (l):
            data3=conn.recv(size)
            #print 'Recieved: ',data3
            print
            coded.append(data3)       
    print 'coded string has been recieved....'
    print ('coded string: ' , coded)
d= decoder(coded,d,n)
print d        
    reply = 'OK... your message decrypted as: ' + d
    if not d:
        break
    conn.sendall(reply)
#came out of loop
conn.close()
#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    #start new thread takes 1st argument as a function name to be run, second is the tuple of     arguments to the function.
    start_new_thread(clientthread ,(conn,))

s.close()

客户端:

import socket
from math import *
from random import *
host='localhost'
port=8888
size=2**16
def declare():
        a = sample([5,3],2)
        return (a[0],a[1])
def coder(input_message):
        (p,q)=declare()
        for i in range (1):
                p=2**p-1
        for i in range (1):
                q=2**q-1
        #print p
        #print q
        #print ("n= ",p*q)
        #print a
        def gcd(a,b):
                if a%b==0:
                    return b
                elif a%b > 0:
                    s=a%b
                        return gcd(b,s)
                else:
                    raise ValueError
        n=p*q
        phi=(p-1)*(q-1)
        e=2
        while gcd(phi,e)!=1:
                e+=1
        d=1
        while ((e*d)%phi)!=1:
                d+=1
        public_key=(n,e)
        special_key=(n,d)
        ListOfAsciis=[]
        coded=[]
        breakcoded=[]
        for i in input_message:
                ListOfAsciis.append(ord(i)-48)
        for j in ListOfAsciis:
                coded.append((j**e)%n)
        #print ("e= ",e)
        #print ("d= ",d)
        #print ("coded= ",coded)
        for i in coded:
                breakcoded.append(chr(((i**d) % n)+48))
        #print ('n= ' , n)
        #print str(coded)
        #print coded
        return (d,n,str(coded[0]))
def decoder(codedString,d,n):
        #input_d= input("please enter your private key d: ")
        #input_n= input("please enter your private key n: ")
        #d = int (input_d)
        #n = int (input_n)
        breakcoded=[]
        coded=(codedString)
        print coded;
        for i in range (len(coded)):
                breakcoded.append(chr(((int(coded[i])**d) % n)+48))

        stri= ""
        for i in range (len(breakcoded)):
                stri+=breakcoded[i]
        return stri
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print 'socket created'
s.connect((host,port))
print 'connected'
data=s.recv(size)
print 'Recieved: ', data
while True:
    input_message= raw_input("please enter your message: ")
    message = list(input_message)
    s.send(str(len(message)))
##  (p,q)=declare()
    #n=p*q
    (d,n,c)=coder('i')

    n=str(n)
print "                  ",
print "                  ",
print "                  ",
print "                  ",
s.send(n)
print "                                                            ",
d=str(d)
s.send((d))
print "   ",
print "   ",
print "   ",
for i in range (len(message)):
            (d,n,c)=coder(input_message[i])
            print "                                                           ",
            print "   ",
            print "   ",
            s.send((c))
    print 'coded string has been sent to the server....'
    data=s.recv(size)
    print 'Recieved: ', data

现在的问题是程序有时能正常工作,有时不能!在错误的情况下,服务器会通过一次 recv 接收到客户端发送的两个 send 项目。我该怎么办?


请查看以下链接:https://dev59.com/12Mm5IYBdhLWcg3wX-AW#17697651 - JadedTuna
1个回答

17

这是TCP的固有部分。流套接字是字节流,而不是消息流。

所以,事情正如它们应该做的那样。如果您想通过TCP流发送一系列消息,这与将一系列对象保存到文件中完全相同-您需要某种方式来界定消息。这可以是使用文本流简单地使用换行符界定消息,也可以是一个复杂的协议,但它必须是某些内容

有关更多详细信息,请参见此博客文章


1
+1 真棒。这是一个常见的基本误解。链接也非常好。 - Jonathon Reinhart
1
@JonathonReinhart: …这就是为什么我写了一篇关于它的博客文章,在回答了在SO和其他地方反复提出的同样问题之后。我真的希望常见平台总是会失败,即使是在本地主机上发送小消息时也是如此,这样人们就不会在遇到问题之前走得太远了... - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接