Member 14106234 Ответов: 2

Проблема с функцией записи


Всем привет,

Я начинающий программист и не понимаю, почему моя функция write() не работает с этими аргументами. Вот почему я здесь.

Когда я выполняю свою программу, я получил ошибку une с моей функцией записи и с моей функцией чтения. это нормально для моей функции чтения, потому что она зависит от функции записи. Я искал в Google свои аргументы, но думаю, что они хороши. Так что я не понимаю, почему это не работает.

Мой сценарий написан на языке Си.

Что я уже пробовал:

int main(int argc,char **argv)
{
	int sockfd,n;
	char sendline[100];
	char recvline[100];
	struct sockaddr_in servaddr;

	sockfd=socket(AF_INET,SOCK_STREAM,0);
	memset(&servaddr, 0, sizeof (servaddr));

	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(22000);

	inet_pton(AF_INET,"127.0.0.1",&(servaddr.sin_addr));
	printf("%d\n", inet_pton(AF_INET,"198.168.1.19",&(servaddr.sin_addr)));

	connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

	while(1)
	{
		memset(sendline,0, 100);
		memset( recvline,0, 100);

		fgets(sendline,100,stdin);

		if(write(sockfd,sendline,strlen(sendline)+1) < 0)
		{
			printf("The write function doesn't work !\n");
   		}
		if(read(sockfd,recvline,100) < 0)
		{
			printf("The read function doesn't work !\n");
		}
		printf("%s",recvline);
	}
}

jsc42

Захватите фактический код ошибки из "записи" и включите его в свое сообщение об ошибке. Затем посмотрите код - это должно дать вам ключ к разгадке, в чем заключается ошибка.
напр.

int errcode;
if ((errcode = write(sockfd, sendline, strlen(sendline) + 1)) < 0)
printf("функция записи вернула %d\n", errcode);

Кроме того, я подозреваю, что вам может понадобиться '&' перед аргументом recvline в функции read (рад быть исправленным, если я ошибаюсь).

Rick York

Нет, в этом нет необходимости. Массив без индекса-это то же самое, что указатель на массив, поэтому & не требуется.

Member 14106234

Мой код ошибки для моей функции чтения и записи равен -1, а & перед recvline ничего не меняет. Для меня проблема в функции чтения-это аргумент "sockfd", потому что у нас уже есть проблема с ним в функции записи.

2 Ответов

Рейтинг:
4

Richard MacCutchan

При записи в файловый дескриптор сокета это похоже на использование функция sendto | Microsoft Docs[^] функция. Поэтому вам нужно использовать функцию WSAGetLastError, чтобы выяснить, почему она не удалась.


Member 14106234

С WSAGetLastError, я получаю, для ошибки 3 : 10093. Поэтому я использовал WSAStartup() и WSACleanup (), потому что я забыл об этом, и я переназначил запись и чтение с помощью send и recv. С этим моя программа работает.
Спасибо вам всем !

Рейтинг:
1

Rick York

В дополнение к тому, что написал jsc42, вызовите strerror (), чтобы получить текстовое описание ошибки и отобразить его. Вот вам пример:

int errorCode;
errorCode = write( sockfd, sendline, strlen( sendline ) + 1 );
if( errorCode < 0 )
{
    fprintf( stderr, "write function failed %d : %s\n", errorCode, strerror( errorCode ) );
}
Еще одна вещь - я заметил, что вы использовали "магическое число" 100 во многих местах. Это не очень хорошая идея. Что произойдет, если вы решите поддерживать до 128 символов? У вас есть целая куча мест, где он должен измениться, и есть вероятность упустить одно. Гораздо лучше использовать определение в языке Си или постоянное значение в языке Си++. Вот код, использующий определение макроса :
#define BUFFER_SIZE  100

int main(int argc,char **argv)
{
	int sockfd,n;
	char sendline[BUFFER_SIZE];
	char recvline[BUFFER_SIZE];
	struct sockaddr_in servaddr;

	sockfd=socket(AF_INET,SOCK_STREAM,0);
	memset(&servaddr, 0, sizeof (servaddr));

	servaddr.sin_family=AF_INET;
	servaddr.sin_port=htons(22000);

	inet_pton(AF_INET,"127.0.0.1",&(servaddr.sin_addr));
	printf("%d\n", inet_pton(AF_INET,"198.168.1.19",&(servaddr.sin_addr)));

	connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

	while(1)
	{
		memset( recvline, 0, sizeof( recvline ) );
		memset( sendline, 0, sizeof( sendline ) );

		fgets( sendline, sizeof( sendline )-1, stdin );

		if( write( sockfd, sendline, strlen(sendline) + 1 ) < 0 )
		{
			printf("The write function doesn't work !\n");
		}
		if( read( sockfd, recvline, sizeof( sendline ) - 1 ) < 0 )
		{
			printf("The read function doesn't work !\n");
		}
		printf( "%s",recvline );
	}
}
Теперь, если вы хотите иметь другой максимальный размер, вы меняете только одну вещь и ничего больше.

Вы заметили -1 в fgets и прочитали вызовы? Они существуют по той же причине, по которой у вас есть +1 в вызове write - для учета завершающего нулевого символа.


Member 14106234

Прежде всего, спасибо за ваш ответ. С помощью strlen(errorCode) Я получаю "неизвестную ошибку". И спасибо, я не думал об определении.

Member 14106234

А -1 в fgets и +1 в вызове write предназначены для завершающего нулевого символа.

Rick York

Являются ли функции записи и чтения вашей собственной реализацией? Я считаю, что функции библиотеки сокетов-это send и recv. Убедитесь, что вы возвращаете те же значения, которые они возвращают из ваших функций, иначе strerror не будет работать правильно.

Еще одна вещь - с последним материалом, который я написал, я обнаружил, что чтение сразу после записи всегда терпит неудачу. Если я поставлю задержку в 1 миллисекунду между вызовами, то это сработает, так что вы, возможно, захотите попробовать. В Win32 API эта функция называется Sleep. Я не знаю, как это называется в других ОС.

Member 14106234

Функция записи и чтения находится на stdio.h, я пробовал использовать send и recv, но получаю ту же ошибку. И функция сна, она ничего не меняет