QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 646|回复: 3

some questions about a socket

[复制链接]
发表于 2003-6-2 10:33:23 | 显示全部楼层 |阅读模式
i have written a ser.c:
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<errno.h>
#define TTL_OUT 128
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
main()
{
int sockfd,client_fd,sin_size,new_sock,len,on=1; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in remote_addr; /* 客户端地址信息 */
struct ip ip_head;
struct ip_timestamp ip_ts;
char buf[20];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket创建出错!"); exit(1);
}
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),;
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))== -1){
perror("bind出错!");
exit(1);
}
if (listen(sockfd, BACKLOG) == -1){
perror("listen出错!");
exit(1);
}
while(1){
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr,&sin_size))==-1){
perror("accept出错");
continue;
}
printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
if (!fork()) { /* 子进程代码段 */
//if (send(client_fd, "Hello, you are connected!n", 26, 0) == -1)
// perror("send出错!");
new_sock=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);
if(new_sock<0){
printf("raw socket failure %d\n",errno);
perror("socket:");
exit(1);
}
if(setsockopt(new_sock,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on))<0){
printf("setsockopt failure %d\n",errno);
perror("server:");
exit(1);
}
ip_head.ip_v=IPVERSION;
ip_head.ip_hl=10;
ip_head.ip_tos=0;
ip_head.ip_len=htons(4*ip_head.ip_hl+sizeof(buf));
ip_head.ip_id=0;
ip_head.ip_off=0;
ip_head.ip_ttl=TTL_OUT;
ip_head.ip_p=IPPROTO_TCP;
ip_head.ip_sum=0;
ip_head.ip_dst=remote_addr.sin_addr;
ip_head.ip_src=my_addr.sin_addr;
len=sizeof(struct ip);
ip_ts.ipt_code=68;
ip_ts.ipt_len=20;
ip_ts.ipt_flg=3;
ip_ts.ipt_oflw=0;
ip_ts.ipt_ptr=4;
ip_ts.data[1]=my_addr.sin_addr.s_addr;
ip_ts.data[3]=remote_addr.sin_addr.s_addr;
strcpy(buf,"This is the messenge!");
printf("send ip_head : %d ,ip :%d\n",ip_head.ip_hl*4,ip_head.ip_len);
sendto(client_fd,buf,len,0,(struct sockaddr*)&remote_addr,sizeof(struct sockaddr_in));
close(client_fd);
close(new_sock);
exit(0);
}
close(client_fd);
}
}

and a cli.c:
/******* 客户端程序 client.c ************/
#include<stdio.h>
#include<iostream.h>
#include&lt;string.h&gt;
#include&lt;sys/types.h&gt;
#include&lt;sys/socket.h&gt;
#include&lt;netinet/in.h&gt;
#include&lt;netinet/ip.h&gt;
#include&lt;errno.h&gt;
#include&lt;netdb.h&gt;
int main(int argc, char *argv[])
{
int sockfd,n,iphead_len,ip_len;
char buffer[1024],ip_head_buf[20];
struct sockaddr_in server_addr;
struct sockaddr_in my_addr;
struct hostent *host;
struct ip *ip_p;
int portnumber,nbytes;

if(argc!=3)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}

if((host=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"Gethostname error\n");
exit(1);
}

if((portnumber=atoi(argv[2]))&lt;0)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}

/* 客户程序开始建立 sockfd描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
exit(1);
}
//my_addr.sin_family=AF_INET;
//my_addr.sin_port=0;
//my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
//bzero(&amp;(my_addr.sin_zero),;
//if(bind(sockfd,(struct sockaddr*)&amp;my_addr,sizeof(struct sockaddr))&lt;0){
//  printf("bind failure %d\n",errno);
//  perror("bind");
// exit (1);
//}
/* 客户程序填充服务端的资料 */
bzero(&amp;server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*(struct in_addr*)host-&gt;h_addr;

/* 客户程序发起连接请求 */
if(connect(sockfd,(struct sockaddr *)(&amp;server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
exit(1);
}

/* 连接成功了 */
//if((nbytes=read(sockfd,buffer,1024))==-1)
//{
//fprintf(stderr,"Read Error:%s\n",strerror(errno));
//exit(1);
//}
n=recvfrom(sockfd,ip_head_buf,sizeof(ip_head_buf),0,NULL,NULL);
if (n &lt; 0) {
  printf ("recvfrom failure %d\n",errno);
  perror ("recvfrom:");
  exit (1);
}
ip_p = (struct ip*)ip_head_buf;
iphead_len=ip_p-&gt;ip_hl*4;
ip_len=ip_p-&gt;ip_len;
printf ("recieved iphead : %d , ip : %d\n",iphead_len,ip_len);
cout&lt;&lt;ip_head_buf&lt;&lt;endl;//i just wanna see what is there in the buffer

//buffer[nbytes]='\0';
//printf("I have received:%s\t\n",buffer);
/* 结束通讯 */
//close(sockfd);
exit(0);
}

then
$gcc -o ser ser.c
passed
$g++ -o cli cli.c   //because of the "cout",i used g++
passed

and run
ser display:
received a connection from 202.200.238.214
send ip_head : 40 ,ip :15360
but cli display:
recieved iphead : 16 , ip : 29545
This is the messenge

why the values of the iphead arenot equal,so do the values of ip?
i think the problem is in cli.c,but where?  :-(
发表于 2003-6-2 13:59:35 | 显示全部楼层
你的客户端程序没有看 你的服务器端的代码 我感觉是很混乱 你设定了一个buffer
然后把这个buffer的内容发给的客户端 然后你又设了一个ip头结构 给这个ip头结构设置参数(?)然后打印出来 但是这个ip头结构实际上没有要发送的内容有任何的联系
而且你的参数设定 头长度=10为什么? 总的长度是10*4(?)加上buffer长度
所以我觉得你的服务端的打印数据实在没有什么意义
回复

使用道具 举报

 楼主| 发表于 2003-6-2 16:40:10 | 显示全部楼层
忘了解释一下,我这个程序想要实现的是服务端运行然后等待客户端联接,客户端联接后服务端将buffer中的东西发给客户端,设置原始套接字的原因是我想从客户端读出两端的时间戳的值并进行相减最终求得服务器到客户端的时间,总得思路就是这样,老大给个建议,谢谢
回复

使用道具 举报

发表于 2003-6-2 17:20:52 | 显示全部楼层
你是想做一个hide ip的包吧 (要不就不要设定IPPROTO_IP,IP_HDRINCL)但是你的ip头得要在你发出的buffer里才行
所以你的发送的包和接受的包都是废数据 (所以才会这么大)
基本上client段没有什么问题 但是server端的程序是错误的
你可以看看网上关于隐藏ip的设计文章
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-15 18:26 , Processed in 0.051370 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表