返回信息流本人在linux下面用c写了一个socket程序,抓包发现有Tcp校验和错误,求解决之道
这是一条镜像帖。来源:北邮人论坛 / soft-design / #31365同步于 2008/11/29
该镜像源已超过 30 天没有更新,可能在源站已被删除。
SoftDesign机器人发帖
Tcp 校验和错误~代码在2楼
shot
2008/11/29镜像同步8 回复
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
没有代码难道让我YY一个错误程序。。。。。
【 在 shot (wjc) 的大作中提到: 】
: 本人在linux下面用c写了一个socket程序,抓包发现有Tcp校验和错误,求解决之道
: [upload=1][/upload]
//============================================================================
// Name : proxy.c
// Author : wjc
// Version : 1.0
// Copyright : copyright wjc
// Description : proxy in C, Ansi-style
// Attention : this code runs on linux
//============================================================================
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <asm/ioctls.h>
#include <arpa/inet.h>
#include <netdb.h>
#define LENGTH_OF_LISTEN_QUEUE 10 //length of listen queue in server
#define BUFFER_SIZE 255
#define WELCOME_MESSAGE "welcome to connect the server. "
#define ERROR_MESSAGE "we come across some problems!"
struct Session
{
int sock;
int remt;
int stat;
char buffer[BUFFER_SIZE];
int length;
};
int GetFree(struct Session *s,int count);
int GetMax(int sock,struct Session *s,int count);
int Connect(char *chs,int port);
int StartServ(char *chs,int port);
int main(int argc, char **argv)
{
int servfd,temp,i,maxline=5;
int servport=20000,conport=21;
char * conip="127.0.0.1";
char * servip="0.0.0.0";
struct hostent *hostp;
if(argc>=5)
{
hostp=gethostbyname(argv[3]);
conip=inet_ntoa(*(struct in_addr *)(*hostp->h_addr_list));
conport=atoi(argv[4]);
servip=argv[1];
servport=atoi(argv[2]);
}
servfd=StartServ(servip,servport);
if(servfd<0)
{
exit(1);
}
printf("server started on %d\n",servport);
/*struct timeval timeout;
timeout.tv_sec=60;
timeout.tv_usec=0;*/
struct Session socks[maxline];
fd_set rfd;
fd_set afd;
FD_ZERO(&afd);
FD_SET(servfd,&afd);
for(i=0;i<maxline;i++)
{
socks[i].sock=0;
socks[i].stat=0;
socks[i].remt=0;
strcpy(socks[i].buffer,ERROR_MESSAGE);
socks[i].length=sizeof(ERROR_MESSAGE);
}
while (1)
{
rfd=afd;
if(select(GetMax(servfd,socks,maxline)+1,&rfd,NULL,NULL,NULL)<0)//socket error
{
exit(1);
}
else
{
if(FD_ISSET(servfd,&rfd))
{
puts("receive a connection");
if((temp=GetFree(socks,maxline))!=-1)
{
socks[temp].sock=accept(servfd,0,0);
socks[temp].remt=Connect(conip,conport);
puts("try to connect the server");
if(socks[temp].remt<0)
{
send(socks[temp].sock,socks[temp].buffer,socks[temp].length,0);
close(socks[temp].sock);
socks[temp].stat=0;
puts("can not connect to the server");
puts("shutdown!");
}
else
{
FD_SET(socks[temp].sock,&afd);
FD_SET(socks[temp].remt,&afd);
printf("line %d start to work\n",temp+1);
}
}
else
{
temp=accept(servfd,0,0);
send(temp,ERROR_MESSAGE,sizeof(ERROR_MESSAGE),0);
close(temp);
puts("no enough resource");
puts("shutdown!");
}
}
for(i=0;i<maxline;i++)
{
if(socks[i].stat==1)
{
temp=0;
if(FD_ISSET(socks[i].sock,&rfd))
{
socks[i].length = recv(socks[i].sock,socks[i].buffer,BUFFER_SIZE,0);
if(socks[i].length<=0)
{
temp=1;
}
else
{
send(socks[i].remt,socks[i].buffer,socks[i].length,0);
}
}
if(FD_ISSET(socks[i].remt,&rfd))
{
socks[i].length = recv(socks[i].remt,socks[i].buffer,BUFFER_SIZE,0);
if(socks[i].length<=0)
{
temp=1;
}
else
{
send(socks[i].sock,socks[i].buffer,socks[i].length,0);
}
}
if(temp==1)
{
close(socks[i].sock);
close(socks[i].remt);
socks[i].stat=0;
FD_CLR(socks[i].sock,&afd);
FD_CLR(socks[i].remt,&afd);
printf("shutdown line %d!\n",i+1);
}
}
}
}
}
close(servfd);
return 0;
}
int GetFree(struct Session *s,int count)
{
int i;
for(i=0;i<count;i++)
{
if(s[i].stat==0)
{
s[i].stat=1;
return i;
}
}
return -1;
}
int GetMax(int sock,struct Session *s,int count)
{
int i,max;
max=sock;
for(i=0;i<count;i++)
{
if(s[i].stat==1)
{
if(s[i].sock>max)
max=s[i].sock;
if(s[i].remt>max)
max=s[i].remt;
}
}
return max;
}
int Connect(char *chs,int port)
{
int clifd;
struct sockaddr_in servaddr,cliaddr;
socklen_t socklen = sizeof(servaddr);
if ((clifd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
return -1;
}
bzero(&cliaddr,sizeof(cliaddr));
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htons(INADDR_ANY);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
inet_aton(chs,&servaddr.sin_addr);
servaddr.sin_port = htons(port);
if (bind(clifd,(struct sockaddr*)&cliaddr,sizeof(cliaddr))<0)
{
close(clifd);
return -2;
}
if (connect(clifd,(struct sockaddr*)&servaddr, socklen) < 0)
{
close(clifd);
return -3;
}
return clifd;
}
int StartServ(char *chs,int port)
{
int servfd;
struct sockaddr_in servaddr;
if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("create socket error!\n");
return -1;
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port);
inet_aton(chs,&servaddr.sin_addr);
//servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(servfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
{
printf("bind to port %d failure!\n",port);
close(servfd);
return -2;
}
if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0)
{
printf("call listen failure!\n");
close(servfd);
return -3;
}
return servfd;
}
赞格式
【 在 shot (wjc) 的大作中提到: 】
: //============================================================================
: // Name : proxy.c
: // Author : wjc
: ...................
baidu说出现这种情况有可能是网卡驱动不支持硬件计算校验和,
有没有方法可以强制用软件的方法计算校验和,这种有错误的
数据包和sina之类的网站通信的时候好像是会被丢弃的。
【 在 flyingmiao 的大作中提到: 】
: tcp的问题应该被socket封装了,用户不需要关心。
: 所以,问题应该不在代码上。
可以自己写校验和 用raw socket
【 在 shot (wjc) 的大作中提到: 】
: baidu说出现这种情况有可能是网卡驱动不支持硬件计算校验和,
: 有没有方法可以强制用软件的方法计算校验和,这种有错误的
: 数据包和sina之类的网站通信的时候好像是会被丢弃的。
: ...................