求助:linux下socket编程(UDP)遇到的诡异现象……
写TFTP服务器时遇到一个很奇怪的问题:
下面两条语句不能用,
struct sockaddr *p=&client_addr;
int ret=sendData(socket_fd,p,1,"hello",5);
但是如果替换为:int ret=sendData(socket_fd,&client_addr,1,"hello",5);
就可以正常执行,不知道为什么……
甚至,这样也不行:
struct sockaddr *p=&client_addr;//只是将&client_addr赋值给p,但是下面不用p也错……
int ret=sendData(socket_fd,&client_addr,1,"hello",5);
郁闷中……
完整的代码如下:
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/times.h>
#include <sys/select.h>
#include <sys/socket.h>//for socket
#include <string.h>
#include <netinet/in.h>
const unsigned int BUF_SIZE =512;//TFTP max data length
int socket_init(char *ipString,unsigned short int port);
int sendData(int sock_fd,struct sockaddr *clientAddr,unsigned short block,char *data,int len);//send data to client
int main(int argc,char *argv[])
{
int socket_fd;
socket_fd=socket_init("127.0.0.1",69);//初始化网络,建立网络连接,返回socket_fd
char buf[BUF_SIZE];
int len_addr;
//struct sockaddr addr;
struct sockaddr client_addr;//store client address
bzero(&client_addr,sizeof(struct sockaddr));
int len=0;//store number of bytes recieved
len=recvfrom(socket_fd,buf,BUF_SIZE,0,&client_addr,&len_addr);
/****************************问题代码……********************/
//struct sockaddr *p=&client_addr;
int ret=sendData(socket_fd,&client_addr,1,"hello",5);
/****************************问题代码……********************/
printf("send %d bytes\n",ret);
}
int socket_init(char *ipString,unsigned short int port)
{
int sock_fd;//函数的返回值,建立的socket的文件描述符
int len;
unsigned long ip;//the ip to be binded
struct sockaddr_in tftp_addr;//address to be binded
len=sizeof(struct sockaddr_in);
bzero(&tftp_addr,len);//clear the value of tftp_addr
inet_pton(AF_INET,ipString,&ip);//字符串ip转为二进制ip存入ip变量
#ifdef TEST
fprintf(stdout,"debug:socket_init:ip=%d,port=%d\n",ip,port);
#endif
tftp_addr.sin_addr.s_addr=htonl(ip);//switch host format to network
tftp_addr.sin_family=AF_INET;//ipv4
tftp_addr.sin_port=htons(port);//switch host format to network
tftp_addr.sin_addr.s_addr=htonl(tftp_addr.sin_addr.s_addr); // ip
if( (sock_fd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) <0)
{
perror("socket_init:socket error");
exit(-1);
}
/* Enable address reuse */
int on = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
if( (bind(sock_fd,(struct sockaddr *)&tftp_addr,len)) ==-1)
{
perror("socket_init:bind error");
exit(-1);
}
#ifdef TEST
fprintf(stdout,"debug:socket_init:udp init ok!\n");
#endif
return sock_fd; //返回网络描述符,实际代表一个网络连接
}
int sendData(int sock_fd,struct sockaddr *clientAddr,unsigned short block,char *data,int len)
{
char resOpcode[2];//respose data opcode
char resBlock[2];//data block number
//fill opcode
unsigned short opcode=htons(3);
memcpy(resOpcode,&opcode,2);
//fill block number
unsigned short num=htons(block);
memcpy(resBlock,&num,2);
//fill respose package
char *resPackage=(char *)malloc( sizeof(char) * (2+2+len) );
memcpy(resPackage,resOpcode,2);
memcpy(resPackage+2,resBlock,2);
memcpy(resPackage+4,data,len);
int ret=sendto(sock_fd,resPackage,len+4,0,clientAddr,sizeof(struct sockaddr) );//发送应答报文
fprintf(stdout,"debug:sendData:send %d byte.\n",ret);
return ret;
}