socket 的通信问题(大小端)

juckciy 2011-09-27 07:03:11
/*******************/
server接收:
int recv_with_headerTmp(int fd, char **buf)
{
unsigned long flag;
int len = 0;
int lRet = 0;
int data = 0;
char Tmpbuf[32]={0};
char Tmpbuf1[32]={0};
#if 1
lRet=recv(fd,Tmpbuf,32,0);
if(lRet<=0)
{
printf("recv flag error\n");
return -1;
}

#if 1
flag =atoi(Tmpbuf);
printf("flag=%d\n",flag);
if(flag!=0x51589158)
{
printf("recv bad flag: 0x%8x\n",flag);
return -1;
}
#endif
#endif

lRet=recv(fd,Tmpbuf1,32,0);
if(lRet<=0)
{
perror("lRet,sfadddddd\n");
printf("lRet =%d\n",lRet);
__ERR("recv len error\n");
return -1;
}
len=atoi(Tmpbuf1);
printf("len=%d\n",len);
if(len<=0)
{
__ERR("recv bad len: %d\n",len);
return -1;
}

if(len>=(15*1024*1024))
{
__ERR("recv bad len: %d\n",len);
return -1;
}


*buf =(char *)malloc(len+2);
if(*buf==NULL)
{
//__ERR("new buf failed.\n");
return -1;
}

int offset=0;

while(len)
{
lRet=recv(fd, *buf + offset,len,0);
if(lRet<=0)
{
printf("recv data error\n");
return -1;
}
else
{
offset+=lRet;
len-=lRet;
}
}

printf("recv success buf =%s\n",*buf);
return offset;
}

client发送:int send_with_headerTmp(int fd, char *data, int len)
{
char buf[32] ={0};
char pbuf[32]={0};
unsigned long flag=0x51589158;
sprintf(buf,"%d",flag);
int ret=send(fd,buf,strlen(buf)+1,0);
if(ret<0)
{
__ERR("send flag error\n");
return -1;
}

sprintf(pbuf,"%d",len);
printf("len=%d\n",len);
ret=send(fd,pbuf,strlen(pbuf)+1,0);
if(ret<0)
{
__ERR("send len error\n");
return -1;
}

ret=send(fd,data,len,0);
return ret;
}

同是大端或者同是小端没有问题。 一台大端一台小段通信服务器就会出现recv len error,为什么?能否给出正解?
...全文
511 13 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
juckciy 2011-09-30
  • 打赏
  • 举报
回复
算了,后来发现好像不是字节序的问题。很可能是字节对齐的问题。后来改用结构体的方式。一次性发送接收就没问题了。
Gloveing 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jiangyiaxiu 的回复:]

引用 10 楼 juckciy 的回复:

引用 9 楼 zhll879 的回复:
引用 4 楼 juckciy 的回复:
引用 3 楼 hu330793681 的回复:
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析

呵呵,我只提取了小部分代码。有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网……
[/Quote]
INADDR_ANY 就是 0 ,转不转都一样是0
督门提码 2011-09-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 juckciy 的回复:]

引用 9 楼 zhll879 的回复:
引用 4 楼 juckciy 的回复:
引用 3 楼 hu330793681 的回复:
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析

呵呵,我只提取了小部分代码。有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网络字节序么?比如char buf[1024],难……
[/Quote]
这不加htonl,直接INADDR_ANY 也可以 ,我平时这样还没出现错误。
juckciy 2011-09-27
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhll879 的回复:]
引用 4 楼 juckciy 的回复:
引用 3 楼 hu330793681 的回复:
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析

呵呵,我只提取了小部分代码。有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网络字节序么?比如char buf[1024],难道要逐个转换?好像发送或者接收的包都转成ch……
[/Quote]
socket发送的数据一般都是char型的吧,不然挨个字节序转换确实麻烦。server端这个INADDR_ANY,不加htonl会出现什么情况?
小小蔷薇 2011-09-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 juckciy 的回复:]
引用 3 楼 hu330793681 的回复:
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析

呵呵,我只提取了小部分代码。有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网络字节序么?比如char buf[1024],难道要逐个转换?好像发送或者接收的包都转成char可以不用考虑字节序了。
[/Quote]

我以前见到的一种码流是,只有最开头的有大小端之分,我把开头4个字节处理就好了,里面内容不变的。
你自己要实际去查看传输的内容差异了,或者有什么协议没有的,看下
luciferisnotsatan 2011-09-27
  • 打赏
  • 举报
回复
代码太长,没看。
ntohl
ntohs

n代表net,网络字节序
h代表host,本机字节序
l代表long,4字节
s代表short,2字节

如果是char类型,那就没有字节序之分。
long,short,wchar_t这种多个字节的,才有字节序
juckciy 2011-09-27
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 agoago_2009 的回复:]
同是大端或者同是小端没有问题。 一台大端一台小段通信服务器就会出现error。
建议不管大端小端都都转换为网络字节序
[/Quote]
有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网络字节序么?比如char buf[1024],难道要逐个转换?好像发送或者接收的包都转成char可以不用考虑字节序了。
Gloveing 2011-09-27
  • 打赏
  • 举报
回复
同是大端或者同是小端没有问题。 一台大端一台小段通信服务器就会出现error。
建议不管大端小端都都转换为网络字节序
juckciy 2011-09-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hu330793681 的回复:]
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析
[/Quote]
能收到,第一个能收到,recv_with_headerTmp函数的recv可以正常接收,但第2个recv的返回值为0.这里不明白为什么?
juckciy 2011-09-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 hu330793681 的回复:]
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析
[/Quote]
呵呵,我只提取了小部分代码。有个问题:一般字节序都用ntohl()或者htonl(),难道每个socket包都需要进行发送或者接收时都需要转换成网络字节序么?比如char buf[1024],难道要逐个转换?好像发送或者接收的包都转成char可以不用考虑字节序了。
快乐的小菜鸟 2011-09-27
  • 打赏
  • 举报
回复
代码很长 网络字节序必须相同 不然另外一段收不到 因为无法解析
juckciy 2011-09-27
  • 打赏
  • 举报
回复
/*****client.c******/

# include <stdio.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
# define SERVER_PORT 5432
# define MAX_LINE 256

#define __ERR printf
//struct socksddr_in
// {
// short sin_family; /* AF_INET */
// u_short sin_port;
/* 16特端口号 网络字节顺序*/
// struct in_addr, sin_addr;
/* 32比特IP地址,网络字节顺序*/
// char sin_zero[8]; /* 未用 */
// }
int send_with_headerTmp(int fd, char *data, int len)
{
char buf[32] ={0};
char pbuf[32]={0};
unsigned long flag=0x51589158;
sprintf(buf,"%d",flag);
int ret=send(fd,buf,strlen(buf)+1,0);
if(ret<0)
{
__ERR("send flag error\n");
return -1;
}

sprintf(pbuf,"%d",len);
printf("len=%d\n",len);
ret=send(fd,pbuf,strlen(pbuf)+1,0);
if(ret<0)
{
__ERR("send len error\n");
return -1;
}

ret=send(fd,data,len,0);
return ret;
}
int main(int argc,char * argv[])
{
FILE *fp;
struct hostent *hp;
struct sockaddr_in sin;
char *host;
char buf[MAX_LINE];
int s;
int len;
if(argc==2){
host=argv[1];
}
else {
fprintf(stderr,"usage:simplex-talk host\n");
exit(1);
}
/* 将主机名翻译成对等实体的IP地址 */
hp=gethostbyname(host);
if(!hp) {
fprintf(stderr,"simplex-talk:unknown host:%s\n",host);
exit(1); }
/*建立地址数据结构 */
bzero((char *)&sin,sizeof(sin));
sin.sin_family=AF_INET;
bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
sin.sin_port=htons(SERVER_PORT);
/*主动打开 */
if((s=socket(PF_INET,SOCK_STREAM,0))<0) {
perror("simplex-talk:socket");
exit(1); }
if(connect(s, (struct sockaddr *)&sin,sizeof(sin)) <0 ) {
perror("simplex-talk:connect");
close(s);
exit(1); }
/* 主循:获得并发送文本行 */
send_with_headerTmp(s,"jiangmb\0",8);
}
juckciy 2011-09-27
  • 打赏
  • 举报
回复
# include <stdio.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>

# define SERVER_PORT 5432
# define MAX_PENDING 5
# define MAX_LINE 256
#define __ERR printf
//struct in_addr
//{
// u_long s_addr;

//}

//struct sockaddr_in
// {
// short sin_family; /* AF_INET */
// u_short sin_port;
/* 16特端口号 网络字节顺序*/
// struct in_addr, sin_addr;
/* 32比特IP地址,网络字节顺序*/
// char sin_zero[8]; /* 未用 */
// }
int recv_with_headerTmp(int fd, char **buf)
{
unsigned long flag;
int len = 0;
int lRet = 0;
int data = 0;
char Tmpbuf[32]={0};
char Tmpbuf1[32]={0};

lRet=recv(fd,Tmpbuf,32,0);
if(lRet<=0)
{
printf("recv flag error\n");
return -1;
}


flag =atoi(Tmpbuf);
printf("flag=%d\n",flag);
if(flag!=0x51589158)
{
printf("recv bad flag: 0x%8x\n",flag);
return -1;
}


lRet=recv(fd,Tmpbuf1,32,0);
if(lRet<=0)
{
perror("lRet,sfadddddd\n");
printf("lRet =%d\n",lRet);
__ERR("recv len error\n");
return -1;
}
len=atoi(Tmpbuf1);
printf("atoi(Tmpbuf1) len=%d\n",len);
if(len<=0)
{
__ERR("recv bad len: %d\n",len);
return -1;
}

if(len>=(15*1024*1024))
{
__ERR("recv bad len: %d\n",len);
return -1;
}


*buf =(char *)malloc(len+2);
if(*buf==NULL)
{
//__ERR("new buf failed.\n");
return -1;
}

int offset=0;

while(len)
{
lRet=recv(fd, *buf + offset,len,0);
if(lRet<=0)
{
printf("recv data error\n");
return -1;
}
else
{
offset+=lRet;
len-=lRet;
}
}

printf("recv success buf =%s\n",*buf);
return offset;
}
int main()
{
struct sockaddr_in sin;
char buf[MAX_LINE];
int len;
int s,new_s;

/* 建立地址数据结构 */
bzero((char *)&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_addr=INADDR_ANY;
sin.sin_port=htons(SERVER_PORT);
/* 建立被动连接 */
if((s=socket(PF_INET,SOCK_STREAM,0))<0) {
perror("simplex-talk:socket");
exit(1);
}
if((bind(s,(struct sockaddr *)&sin,sizeof(sin)))<0) {
perror("simplex-talk:bind");
exit(1);
}
listen(s,MAX_PENDING);
/*等待连接,然后接收并输出文本 */

if((new_s=accept(s,(struct sockaddr *)&sin,&len))<0)
{
perror("simplex-talk:accept");
exit(1);
}
char *recv_buf =NULL;
int byte =0;
byte =recv_with_headerTmp(new_s,&recv_buf);
recv_buf[byte]= '\0';
printf("recv=%s\n",recv_buf);
close(new_s);

}
//server.c

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧