Я пытаюсь создать очень простую клиент-серверную чат-программу, где две программы могут общаться друг с другом. Однако функция accept дает мне ошибку «недопустимый аргумент». Я вставляю код здесь:
#include #include #include #include #include #include #include #include int main() { struct sockaddr_in myaddr; struct sockaddr_in otheraddr; int sockid; int bindid; int recvsockid; int clientlen; int connectid; char send_msg[100] = "Program 1", recv_msg[100]; int recvid, sendid; int myport_id = 4550; int otherport_id = 4560; sockid = socket(AF_INET, SOCK_STREAM, 0); //fcntl(sockid, F_SETFL, O_NONBLOCK); if (sockid < 0) { printf("\nCould not create socket"); } bzero((char*)&myaddr, sizeof(struct sockaddr_in)); myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); myaddr.sin_port = htons(myport_id); bzero((char*)&otheraddr, sizeof(struct sockaddr_in)); otheraddr.sin_family = AF_INET; otheraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); otheraddr.sin_port = htons(otherport_id); bindid = bind(sockid, (struct sockaddr*)&myaddr, sizeof(struct sockaddr_in)); if(bindid < 0) printf("bind error \n"); listen(bindid, 5); do { connectid = connect(sockid, (struct sockaddr*)&otheraddr, sizeof(struct sockaddr_in)); if (connectid < 0 && !(errno == EINPROGRESS)) { //printf("%s", strerror(errno)); perror("connect"); exit(1); } recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen); if (recvsockid < 0 && !(errno == EINPROGRESS || errno == EAGAIN)) { perror("accept"); exit(1); } } while (connectid < 0 && recvsockid < 0); do { gets(send_msg); sendid = sendto(sockid, send_msg, 100, 0, (struct sockaddr*)&otheraddr, sizeof(struct sockaddr_in)); fprintf(stderr, "%d", sendid); if(sendid < 0) printf("error3\n"); recvid = recvfrom(recvsockid, recv_msg, 100, 0, (struct sockaddr*)&myaddr, &clientlen); if (recvid < 0) { printf("\nError in receive"); break; } } while (1); return 0; }
Буду признателен, если кто-нибудь скажет мне, почему я получаю эту ошибку и как ее исправить.
Большое спасибо.
Ваша проблема в том, что вы пытаетесь подключиться и прослушивать один и тот же сокет. Я почти уверен, что вы означали bindid
для прослушивания.
Поскольку вы создаете обе стороны TCP-соединения в одной и той же программе, вам нужны два дескриптора сокета, то есть два вызова socket(2)
в установочном коде, один для подключения и один для приема клиентских соединений.
recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen);
Вы не инициализировали clientlen
, если вы посмотрите на документацию для accept ():
address_len Указывает на структуру socklen_t, которая на входе задает длину поставляемой структуры sockaddr, а на выходе задает длину сохраненного адреса.
Итак, установите его до длины myaddr
перед вызовом accept ():
client_len = sizeof myaddr; recvsockid = accept(sockid, (struct sockaddr*)&myaddr, &clientlen);