Сетевое программирование на C (данные не передаются от клиента к серверу с помощью send())
У меня есть два файла: клиент и сервер, я хочу отправить значение переменной (выбор) с клиента на сервер, но значение не отправляется, и я понятия не имею, в чем проблема
это мой код для клиента
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<fcntl.h>
int main(int argc , char *argv[])
{
char buf;
int clientSocket, cnnt,fileDiscriptor,sizeInByte=0 , size=0 , serverSocket,choice=2 ;
struct sockaddr_in serverInfo;
if(argc != 3)
{
printf("Few arguments\nUsage : ./client <ip> <port>\n");
exit(1);
}
memset(&serverInfo,0,sizeof(serverInfo));
serverInfo.sin_family = AF_INET;
inet_aton(argv[1],&serverInfo.sin_addr.s_addr);
serverInfo.sin_port = htons(atoi(argv[2]));
clientSocket = socket(AF_INET,SOCK_STREAM,0);
if(clientSocket < 0)
{
printf("Could not create client socket\n");
exit(1);
}
cnnt = connect(clientSocket,(struct sockaddr *)&serverInfo,sizeof(serverInfo));
if(cnnt < 0)
{
printf("Could not create connection to the server\n");
exit(1);
}
recv(clientSocket , &serverSocket , sizeof(int) , 0);
send(serverSocket , &choice , sizeof(int),0);
close(clientSocket);
return 0;
}
и это мой код для сервера
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <sys/wait.h>
int main(int argc , char *argv[])
{
int choice;
int serverSocket, bnd, lstn , clientSize, connectionFd;
struct sockaddr_in serverInfo, clientInfo ;
if(argc != 2)
{
printf("Few arguments\nUsage : ./server <port>\n");
exit(1);
}
memset(&serverInfo , 0 , sizeof(serverInfo));
memset(&clientInfo , 0 , sizeof(clientInfo));
serverInfo.sin_family = AF_INET;
serverInfo.sin_port = htons(atoi(argv[1]));
serverInfo.sin_addr.s_addr = INADDR_ANY;
serverSocket = socket(AF_INET,SOCK_STREAM,0);
if(serverSocket < 0)
{
printf("Could not create server socket\n");
exit(1);
}
bnd = bind(serverSocket , (struct sockaddr *)&serverInfo , sizeof(serverInfo));
if(bnd < 0)
{
printf("Could not bind\n");
exit(1);
}
lstn = listen(serverSocket , 1);
if(lstn < 0)
{
printf("Could not listen on server socket\n");
exit(1);
}
clientSize = sizeof(clientInfo);
while(1)
{
connectionFd = accept(serverSocket , (struct sockaddr *)&clientInfo , &clientSize);
if(connectionFd < 0)
continue;
send(connectionFd , &serverSocket , sizeof(int) , 0);
recv(serverSocket , &choice , sizeof(int),0);
close(connectionFd);
break;
}
printf("CHOICE IS :%d\n",choice);
return 0;
}
3 ответа
После проверки выясняется, что произошла ошибка при отправке и получении как на клиенте, так и на сервере.
как на странице руководства
ssize_t send (int sockfd, const void * buf, size_t len, int flags);
ssize_t recv (int sockfd, void * buf, size_t len, int flags);
как в моем коде
отправить (clientSocket, & choice, sizeof (int), 0);
recv (serverSocket, & choice, sizeof (int), 0);
что вызывает ошибку, если я применяю каждую функцию правильно?
Ты уверен, что это не так send
-ную? ИМО,
recv(clientSocket , &serverSocket , sizeof(int) , 0);
в клиенте блокирует, тем самым не доходя до send()
вызов. Вы можете поставить recv()
позвонить [что не предназначено и не требуется, IMO] после send()
на стороне клиента?
Подсказка: сервер прослушивает входящее соединение, и, пока нет входящего соединения, у него нет адреса для send
общение обратно.
- Общий поток для сервера: открытый сокет -> связать -> прослушать -> принять -> получить -> отправить.
- Общий поток для клиента: открыть сокет -> подключиться -> отправить -> получить.
РЕДАКТИРОВАТЬ:
Как вы отправляете int
тип, [размер больше 1 байта], я бы рекомендовал использовать htonl()
на стороне клиента и ntohl()
на стороне сервера, чтобы решить проблему с порядком байтов [если есть].
Строка в коде сервера, которая делает:
send(connectionFd , &serverSocket , sizeof(int) , 0);
не нужно, поэтому удалите его. Нет причин отправлять значение сокета сервера клиенту, клиент все равно не может его использовать, файловый дескриптор является ресурсом, связанным с процессом, и вы не можете передать этот ресурс другому процессу, записав его значение поверх TCP-соединение с клиентом.
На клиенте вам нужно отправить переменную выбора для только что открытого соединения, поэтому вам нужно изменить эти 2 строки:
recv(clientSocket , &serverSocket , sizeof(int) , 0);
send(serverSocket , &choice , sizeof(int),0);
К этому:
send(clientSocket , &choice , sizeof(int),0);
В дополнение к этому, вы должны иметь привычку проверять все ваши звонки на наличие ошибок, чтобы вы знали, если что-то не получается, например,
int rc;
rc = send(clientSocket , &choice , sizeof(int),0);
if (rc == -1) {
perror("send()");
//handle error, e.g. exit the app
}