现在的位置: 首页 > 综合 > 正文

OOB套接字传输实例(达不到预期结果)

2019年08月11日 ⁄ 综合 ⁄ 共 3355字 ⁄ 字号 评论关闭

参考资料:<<Linux网络编程.pdf>>page119-205

代码本来是全照书上抄的,后来发现编译不成功,所以就稍微改了下。下面是我修改后的代码:

server.c

// OOB套接字传输服务端(Server.c)

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <fcntl.h>

#define MYPORT 4000
#define BACKLOG 10

int new_fd;

void sig_urg(int signo)
{
	int n;
	char buf[100];
	printf("SIGURG received\n");
	n = recv(new_fd, buf, sizeof(buf)-1, MSG_OOB);
	buf[n] = 0;
	printf("recv %d OOB bytes: %s\n", n, buf);
}

int main(int argc, char *argv[])
{
	int sock_fd;
	struct sockaddr_in my_addr;
	struct sockaddr_in their_addr;
	int sin_size, n;
	char buf[100];

	if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket");
		return 1;
	}
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(MYPORT);
	my_addr.sin_addr.s_addr = INADDR_ANY;	// 自动设置为自己的IP
	bzero(&(my_addr.sin_zero), 8);			// 将结构的其余空间清零

	if(bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1)
	{
		perror("bind");
		return 1;
	}
	if(listen(sock_fd, BACKLOG) == -1)
	{
		perror("listen");
		return 1;
	}
	void *old_sig_urg_handle;				// 保存系统默认的信号处理函数
	if((old_sig_urg_handle = signal(SIGURG, sig_urg)) == SIG_ERR)
	{
		perror("signal");
		return 1;
	}
	fcntl(sock_fd, F_SETOWN, getpid());

	while(1)
	{
		sin_size = sizeof(struct sockaddr_in);
		if((new_fd = accept(sock_fd, (struct sockaddr*)&their_addr, &sin_size)) == -1)
		{
			perror("accept");
			continue;
		}
		printf("server: got connection from [%s]\n", inet_ntoa(their_addr.sin_addr));
		if(!fork())
		{
			while(1)
			{
				if((n = recv(new_fd, buf, sizeof(buf)-1, 0)) <= 0)		// 接收正常数据
				{
					printf("recv EOF\n");
					break;
				}
				buf[n] = 0;
				printf("Recv: %d bytes: %s\n", n, buf);
				close(new_fd);
			}
			exit(0);
		}
	}
	while(waitpid(-1, NULL, WNOHANG) > 0);
	signal(SIGURG, old_sig_urg_handle);		// 恢复系统默认的信号处理函数

	return 0;
}

Client.c

// OOB套接字传输客户端(Client.c)

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MYPORT 4000
#define MAXDATASIZE 100

int main(int argc, char *argv[])
{
	int sock_fd;
	char buf[MAXDATASIZE];
	struct hostent *he;
	struct sockaddr_in their_addr;

	if(argc < 2)
	{
		fprintf(stderr, "Usage: %s <hostname>\n", argv[0]);
		return 1;
	}
	if((he = gethostbyname(argv[1])) == NULL)
	{
		herror("gethostbyname");
		return 1;
	}
	if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		perror("socket");
		return 1;
	}

	their_addr.sin_family = AF_INET;
	their_addr.sin_port = htons(MYPORT);
	their_addr.sin_addr = *((struct in_addr*)he->h_addr);
	bzero(&(their_addr.sin_zero), 8);

	if(connect(sock_fd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1)
	{
		perror("connect");
		return 1;
	}
	if(send(sock_fd, "123", 3, 0) == -1)
	{
		perror("send");
		close(sock_fd);
		return 0;
	}
	printf("Send 3 bytes of normal data\n");
	sleep(1);

	if(send(sock_fd, "4", 1, MSG_OOB) == -1)
	{
		perror("send");
		close(sock_fd);
		return 0;
	}
	printf("Send 1 byte of OOB data\n");
	sleep(1);

	if(send(sock_fd, "56", 2, 0) == -1)
	{
		perror("send");
		close(sock_fd);
		return 0;
	}
	printf("Send 2 bytes of normal data\n");
	sleep(1);

	if(send(sock_fd, "7", 1, MSG_OOB) == -1)
	{
		perror("send");
		close(sock_fd);
		return 0;
	}
	printf("Send 1 byte of OOB data\n");
	sleep(1);

	if(send(sock_fd, "89", 2, MSG_OOB) == -1)
	{
		perror("send");
		close(sock_fd);
		return 0;
	}
	printf("Send 2 bytes of OOB data\n");
	sleep(1);

	close(sock_fd);

	return 0;
}

运行结果:

1. Server端:

[zcm@socket #39]$./myserver 
server: got connection from [127.0.0.1]
Recv: 3 bytes: 123
recv EOF

2. 客户端:

[zcm@socket #25]$./myclient localhost
Send 3 bytes of normal data
Send 1 byte of OOB data
Send 2 bytes of normal data
Send 1 byte of OOB data
Send 2 bytes of OOB data
[zcm@socket #26]$

 

现在的疑问是:我感觉signal函数虽然调用成功了,但是没起到作用。我认为正常情况下,sig_urg()应该会被调用,但结果是好像他没有收到SIGURG信号,所以没有调用sig_urg这个函数。

 

若有高人能解决,小弟万分感激!

抱歉!评论已关闭.