IDoSomething
2021-08-25 08:25
采纳率: 100%
浏览 62

兄弟姐妹们,遇到个socket编程的问题,跟发送带外数据有关😭

使用send函数发送带外数据给服务器端,我带上OOB_MSG了;服务器端用触发SIGURG信号调用函数接收我的带外数据和正常数据。
但是输出数据咋只有正常数据,没看到我的带外数据。
我wires hark抓包看有URG标记的包,但就是输出不来,这个信号处理函数没被调用
奇怪的是有时换个端口就输出来了oob数据,但是绝大多数情况下输出不来oob数据
img

//服务器端
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <iostream>
using namespace std;

#define BUFFER_SIZE 1024

static int connfd;

/*SIGURG信号的处理函数*/
void sig_urg(int sig)
{
    int save_errno = errno;
    char buffer[BUFFER_SIZE];
    memset(buffer, '\0', BUFFER_SIZE);
    int ret = recv(connfd, buffer, BUFFER_SIZE - 1, MSG_OOB); assert(ret >= 0);
    printf("got %d bytes of oob data %s \n", ret, buffer);
    errno = save_errno;
}

void addsig(int sig, void (*sig_handler)(int))
{
    printf("test\n");
    struct sigaction sa;
    memset(&sa, '\0', sizeof(sa));
    sa.sa_handler = sig_handler;
    sa.sa_flags |= SA_RESTART;
    sigfillset(&sa.sa_mask);
    assert(sigaction(sig, &sa, NULL) != -1);
}

int main(int argc, char * argv[])
{
    if(argc <= 2)
    {
        printf("usages: %s ip_address port_number\n", basename(argv[0]));
        return 1;
    }

    const char* ip = argv[1];
    int port = atoi(argv[2]);

    struct sockaddr_in address;
    bzero(&address, sizeof(address));
    address.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &address.sin_addr);
    address.sin_port = htons(port);

    int listenfd = socket(PF_INET, SOCK_STREAM, 0); assert(listenfd >= 0);

    int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address)); assert(ret != -1);

    ret = listen(listenfd, 5); assert(ret != -1);

    struct sockaddr_in client_address;
    socklen_t client_addrlength = sizeof(client_address);
    int connfd = accept(listenfd, (struct sockaddr*)&client_address, &client_addrlength);
    if(connfd < 0) printf("errno is %d\n", errno);
    else
    {
        addsig(SIGURG, sig_urg);
        ret = fcntl(connfd, F_SETOWN, getpid());    //使用SIGURG信号须设置socket的宿主进程或进程组

        char buffer[BUFFER_SIZE];
        while(1)
        {
            memset(buffer, '\0', BUFFER_SIZE);
            ret = recv(connfd, buffer, BUFFER_SIZE -1, 0);
            if(ret <= 0) break;
            printf("got %d bytes of normal data %s \n", ret, buffer);
        }
        close(connfd);
    }
    close(listenfd);
    return 0;
}

//客户端
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
using namespace std;
int main(int argc, char * argv[])
{
    const char * ip = argv[1];
    int port = atoi(argv[2]);

    struct sockaddr_in address;
    bzero(&address, sizeof address);
    address.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &address.sin_addr);
    address.sin_port = htons(port);

    int sock = socket(PF_INET, SOCK_STREAM, 0);
    assert(sock >= 0);

    if(connect(sock, (struct sockaddr*)&address, sizeof address) < 0) printf("connected failed\n");
    else
    {
        const char * oob_data = "abcdefghi";
        const char * normal_data = "123456789";
        send(sock, normal_data, strlen(normal_data), 0);
        send(sock, oob_data, strlen(oob_data), MSG_OOB);
        send(sock, normal_data, strlen(normal_data), 0);
    }
    close(sock);
    return 0;
}

  • 好问题 提建议
  • 收藏

2条回答 默认 最新

  • IDoSomething 2021-08-25 09:46
    已采纳

    感谢,结案了,我打印errno的值看到Socket operation on non-socket,然后发现服务器端的代码16行和65行有问题,65行前多加了个int。。

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • 将 fcntl 上移一行

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题