gpt4 book ai didi

c - SCTP 服务器无法通过 channel 向客户端发送消息

转载 作者:行者123 更新时间:2023-11-30 16:05:51 25 4
gpt4 key购买 nike

服务器从客户端接收消息,但通过3个 channel 发送回客户端时,sctp_recvmsg函数返回-1。有时当我运行它时它会起作用,但它每隔一段时间就会发生一次。各位大佬帮我解答一下!

服务器占用一个空闲端口并显示它以连接到客户端。之后,它监听套接字并等待来自客户端的连接。连接后,将创建一个用于客户服务的单独流。流接收到消息后,通过三个 channel 将接收到的消息发送回客户端。

服务器

  #include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <iostream>
#include <thread>
#include <vector>

using namespace std;

vector<thread> threadPool;

void multichatThread(int newsock, int flags)
{

char buffer[512];

printf("Новый клиент!\n");
struct sctp_sndrcvinfo sndrcvinfo; // информация о пересылке
if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{ // принимаем сообщение от клиента
printf("Error sctp_recvmsg!\n");
return;
}
printf("%s\n", buffer);
int i;
for (i = 0; i < 3; i++)
{ // по всем 3-м потокам отправляем информацию
if (sctp_sendmsg(newsock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, i, 0, 0) == -1)
{ // отправляем клиенту сообщение
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}
}
close(newsock); // закрываем связь с клиентом
}

void createServer()
{
struct sockaddr_in server, client;
int sock;
// создание сокета
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create socket!\n");
return;
}
// структура для сервера
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY); // локальный адрес
server.sin_port = htons(0); // порт сервера
// связка
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error bind!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
initmsg.sinit_num_ostreams = 3; // входные потоки
initmsg.sinit_max_instreams = 3; // выходные потоки
initmsg.sinit_max_attempts = 2; // максимальное количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));

// объявляем очередь
if (listen(sock, 5) == -1)
{
printf("Error listen!\n");
return;
}
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (getsockname(sock, (struct sockaddr *)&sin, &len) == -1)
perror("getsockname");
else
{
printf("Сервер создан!\n");
printf("IP: %s\n", inet_ntoa(sin.sin_addr));
printf("Port: %d\n", ntohs(sin.sin_port));
}

int newsock;
int clnlen = sizeof(client), flags;
while (true)
{
if ((newsock = accept(sock, (struct sockaddr *)&client, (socklen_t *)&clnlen)) == -1)
{
printf("Error accept!\n");
return;
}

thread chatThread(multichatThread, newsock, flags);
chatThread.detach();
threadPool.push_back(move(chatThread));
}
close(sock); // закрываем сокет сервера
}

int main()
{
createServer();
return 0;
}

客户端接收端口并连接到服务器。然后它通过三个 channel 向服务器发送消息并等待服务器的响应。

客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <iostream>

using namespace std;

void connectServer(string ip, uint16_t port)
{
// настройка структуры для сервера
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(port);
// создаем сокет
int sock;
if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1)
{
printf("Error create!\n");
return;
}
// настройка канала
struct sctp_initmsg initmsg;
memset(&initmsg, 0, sizeof(initmsg));
initmsg.sinit_num_ostreams = 3; // выходные потоки
initmsg.sinit_max_instreams = 3; // входные потоки
initmsg.sinit_max_attempts = 2; // количество попыток
setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, sizeof(initmsg));

struct sockaddr_in sin;
socklen_t len = sizeof(sin);

printf("Данные о сокете!\n");
printf("IP: %s\n", inet_ntoa(server.sin_addr));
printf("Port: %d\n", ntohs(server.sin_port));

// соединяемся с сервером
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == -1)
{
printf("Error connect!\n");
return;
}
// отправка и прием сообщения
char buf[512] = "Hello!";
if (sctp_sendmsg(sock, (void *)buf, (size_t)strlen(buf), NULL, 0, 0, 0, 1 /* номер потока */, 0, 0) == -1)
{
printf("Ошибка отправки пакета к серверу!\n");
return;
}
struct sctp_sndrcvinfo sndrcvinfo;
int i, flags;
char buff[512];
for (i = 0; i < 3; i++)
{ // по 3-м каналам принимаем сообщения
bzero((void *)&buff, sizeof(buff));
if (sctp_recvmsg(sock, (void *)buff, sizeof(buff), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{

printf("Ошибка отправки пакета от сервера!\n");
return;
}
printf("Сервер: %s\n", buff);
}
close(sock);
}
int main()
{

string ip;
uint16_t port;
cout << "Введите IP:";
cin >> ip;
cout << "Введите PORT:";
cin >> port;

connectServer(ip, port);

return 0;
}

最佳答案

首先,检查错误时的 errno 值 - 这可能会有所帮助。

if (sctp_recvmsg(newsock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags) == -1)
{
int ec = errno;
printf("Error sctp_recvmsg %d - %s!\n", ec, strerror(ec));
return;
}

关于c - SCTP 服务器无法通过 channel 向客户端发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60151004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com