Я пытаюсь читать и писать в сокет, используя сетевое программирование linux в C. Я делаю успешные вызовы "писать" и "читать" в клиентских и серверных программах соответственно.
Часть, с которой я с трудом понимаю, заключается в том, что в моей клиентской программе я петлю и вызываю запись 5 раз, на сервере, я петлю и вызываю чтение 5 раз.
Это ожидаемый результат:
MSG: I got your message MSG: I got your message MSG: I got your message MSG: I got your message MSG: I got your message
Это фактический результат:
MSG: I got your messageI got your messageMSG: I got your messageI got your messageMSG: I got your messageMSG: MSG:
Поскольку вы можете видеть ожидаемый результат, а фактический вывод отличается. Похоже, клиент может позвонить "написать" дважды, прежде чем он будет отправлен.
Это то, что у меня есть для клиентского кода
for(int i=0;i<5;i++)
{
int n = write(ssocket.socketFileDescriptor,"I got your message",18);
cout<<n<<" number of bytes written."<<endl;
if (n < 0) socketError("ERROR writing to socket");
}
Это код сервера:
void* run(void* arg)
{
ServerSocket* ss = (ServerSocket*)arg;
//while(true)
for(int i=0;i<5;i++)
{
char buffer[256];
bzero(buffer,256);
int n = read(ss->newsockfd,buffer,256);
printf("MSG: %s",buffer);
}
close(ss->newsockfd);
}
Это дополнение к вопросу ниже, который устарел на данном этапе.
Неужели я пропустил вызов флеша или что-то еще?
Ваш клиент и сервер просто не скоординированы. Клиент записывает сообщение 5 раз как можно быстрее, и сервер читает пять раз быстрее, чем он может. В вашем примере вывода, очевидно, при первом вызове read()
клиент отправил сообщение дважды, а во втором вызове read()
он отправил его еще два раза. Вы read()
до 256 символов, и каждый раз, когда вы его вызываете, он просто пытается прочитать что-либо, что в настоящее время находится в буфере. Если к этому времени клиент отправляет несколько сообщений, read()
будет просто захватывать все.
Обычно вам нужен какой-то тип синхронизации, например, после отправки одного сообщения клиент ожидает, что сервер отправит "OK"
или что-то подобное, прежде чем отправит второе сообщение. Кроме того, вы можете использовать какой-то маркер конца сообщения (например, новую строку), чтобы сервер мог отличить их, если у вас очень простой формат связи.