IDoSomething 2021-08-25 08:25 采纳率: 100%
浏览 72
已结题

兄弟姐妹们,遇到个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。。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 9月2日
  • 已采纳回答 8月25日
  • 创建了问题 8月25日

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题