版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zeqi1991/article/details/81588575
外带数据使用recv接受,只是最后一个参数要是MSG_OOB,但是怎么判断这次的数据是MSG_OOB,那就需要使用select来处理.
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cassert>
#include <unistd.h>
#include <fcntl.h>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
int main(int argc, char *argv[])
{
if (argc <= 2)
return -1;
const char* ip = argv[1];
int port = atoi(argv[2]);
int ret = 0;
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(port);
if (1 != ::inet_pton(AF_INET, ip, &address.sin_addr))
return -1;
int listen_fd = ::socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd == -1)
return -1;
ret = ::bind(listen_fd, (struct sockaddr*)&address, sizeof(address));
if (ret == -1)
return -1;
ret = ::listen(listen_fd, 5);
if (ret == -1)
return -1;
struct sockaddr_in client_address;
socklen_t client_address_len = sizeof(client_address);
int conn_fd = ::accept(listen_fd, (struct sockaddr*)&client_address, &client_address_len);
if (conn_fd==-1)
{
::close(listen_fd);
return -1;
}
char buf[1024] = {0};
fd_set read_fds, exception_fds;
FD_ZERO(&read_fds);
FD_ZERO(&exception_fds);
while (true)
{
bzero(buf, sizeof(buf));
FD_SET(conn_fd, &read_fds);
FD_SET(conn_fd, &exception_fds);
//最后一个参数传NULL,表示一直等待
ret = ::select(conn_fd+1, &read_fds, NULL, &exception_fds, NULL);
if (ret <= 0)
break;
if (FD_ISSET(conn_fd, &read_fds))
{
ret = ::recv(conn_fd, buf, 1024-1, 0);
if (ret <= 0)
break;
else
cout << buf << endl;
}
else if (FD_ISSET(conn_fd, &exception_fds))
{
ret = ::recv(conn_fd, buf, 1024-1, MSG_OOB);
if (ret <= 0)
break;
else
cout << buf << endl;
}
//68~75处理外带数据
}
::close(conn_fd);
::close(listen_fd);
return 0;
}