Я знаю, что это может быть глупо, но мой пакет сообщений, определенный с помощью буферов протокола Google, плохо работает с UDP, в то время как он отлично работает с TCP.
Когда я посылаю обычную строку из сериализованного пакета (в котором у меня есть только несколько простых полей) с клиента на сервер через UDP, все в порядке. Но когда я добавляю повторяющееся поле, сериализованная строка может быть получена только частью целого. Первое поле будет получено полностью, а все остальное будет потеряно.
Код написан на c ++, буферы протокола Google 2.3.0, Linux.
Любая помощь приветствуется.
Спасибо.
Мой файл протока находится ниже:
message Package{
optional string virtualPath = 1;
optional int32 num = 2;//0=insert, 1=find, 2=remove.
optional string realFullPath = 3;
optional bool isDir = 4;
repeated string listItem = 5;
optional int32 openMode = 6;
optional int32 mode = 7;
optional int32 Operation = 8;
optional int32 replicaNo =9;
}
Серверная сторона:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "zht_util.h"
int main(int argc, char *argv[]) {
struct sockaddr_in sad;
int port = 50000;
struct sockaddr_in cad;
int alen;
int serverSocket;
char clientSentence[1000];
char capitalizedSentence[1000];
char buff[1000];
int i, n;
serverSocket = socket(PF_INET, SOCK_DGRAM, 0); /* CREATE SOCKET */
if (serverSocket < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
memset((char *) &sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons((u_short) port);
if (bind(serverSocket, (struct sockaddr *) &sad, sizeof(sad)) < 0) {
fprintf(stderr, "bind failed\n");
exit(1);
}
while (1) {
clientSentence[0] = '\0';
alen = sizeof(struct sockaddr);
socklen_t len = (socklen_t) alen;
n = recvfrom(serverSocket, buff, sizeof(buff), 0,
(struct sockaddr *) &cad, &len);
strncat(clientSentence, buff, n);
printf("Server received :%s \n", clientSentence);
}
return 0;
}
Клиентская сторона:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "zht_util.h"
int main(int argc, char *argv[])
{
struct sockaddr_in sad;
int clientSocket;
struct hostent *ptrh;
char *host;
int port;
char Sentence[1000];
char modifiedSentence[1000];
char buff[1000];
int n;
host = "localhost";
port = 50000;
clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
if (clientSocket < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
memset((char *)&sad,0,sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_port = htons((u_short)port);
ptrh = gethostbyname(host);
if ( ((char *)ptrh) == NULL ) {
fprintf(stderr,"invalid host: %s\n", host);
exit(1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
HostEntity destination;
destination.host = "localhost";
destination.port = 50000;
int current_sock = -1;
Package package;
package.set_virtualpath(randomString(25));
package.add_listitem("item--1");
package.add_listitem("item--2");
package.add_listitem("item--3");
package.add_listitem("item--4");
package.add_listitem("item--5");
package.set_realfullpath("Some-Real-longer-longer-and-longer-Paths");
cout << "package size: " << package.ByteSize() << endl;
char array[package.ByteSize()];
package.SerializeToArray(array, package.ByteSize());
strcpy(Sentence, array);
n=sendto(clientSocket, Sentence, strlen(Sentence)+1,0 ,
(struct sockaddr *) &sad, sizeof(struct sockaddr));
printf(" Client sent %d bytes to the server\n", n);
close(clientSocket);
return 0;
}
Для проблемы, о которой упоминал Джон, я тоже пробовал, все равно не работает.
string Sentence = package.SerializeAsString();
n=sendto(clientSocket, Sentence.c_str(), (Sentence.size())+1,0 ,(struct sockaddr *) &sad, sizeof(struct sockaddr));