一般的网络程序在通信时都会使用系统给与的IP进行通信,但是对于一个具有多个IP和网络设备的运行环境,比如:ETH0:1、ETH0:2 ……,想要有选择的使用IP资源就要进行特殊的控制。
Bind()提供给我们一个将socket与设备和地址联系起来的方法。一般我们只在写服务端程序时使用bind(),它将INADDR_ANY宏与SOCKET联系起来,很少在客户程序使用它,那就让我们尝试在客户程序中试一下它的作用吧。
http://leadgenius.cublog.cn/
基本流程是
确定网络设备à获得设备地址à将地址与SOCKET联系起来à建立连接
由于我写的是一个自动的网络投票器,过程麻烦一点,根据需要简化吧。
注意
int lgxsocket_tcpclient_srcipconnect(char *srcip, char *hostname, int port)
中bind和connect的设置过程,一个是设置通信源,后者是设置目标的。
其中乐趣仔细品味。
(赋投票器源码)
/* bindip.c
* a test program to change eth interface when multi_ethdev exist.
* for little wangwang
*
* 20070512
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
ifindex = iface_get_id(sock_fd, devname);
if(ifindex < 0) return 0;
if(!iface_bind(sock_fd, ifindex)) return 0;
fprintf(stderr, "3333333333333333333333\n");
*/
int lgxsocket_getifid(int fd, const char *devname)
{
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1)
{
return -1;
}
return ifr.ifr_ifindex;
}
/* bind socket filds with ifindex
* for open socket by socket(AF_PACKET, SOCK_RAW,htons(ETH_P_IP)
*/
int lgxsocket_bindifid(int fd,int ifindex)
{
struct sockaddr_ll sll;
memset( &sll, 0, sizeof(sll) );
sll.sll_family = AF_INET; //AF_PACKET;
sll.sll_ifindex = ifindex;
sll.sll_protocol = htons(INADDR_ANY); // htons(ETH_P_ALL);
if(bind(fd, (struct sockaddr *)&sll, sizeof(sll)) == -1)
{
return 0;
}
return 1;
}
static struct in_addr lgxsocket_gethost(char * host)
{
struct in_addr addr;
struct hostent * he;
if(NULL == (he = gethostbyname(host))){
printf("lgxsocket_gethost():Can not get address by %s\n",host);
bzero(&(addr),sizeof(struct in_addr));
return addr;
}
memcpy(&addr, he->h_addr, sizeof addr);
return addr;
}
int lgxsocket_tcpclient_srcipconnect(char *srcip, char *hostname, int port)
{
struct sockaddr_in server_addr;
struct sockaddr_in local_addr;
int sock_fd;
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) return 0;
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(0);
local_addr.sin_addr = lgxsocket_gethost(srcip);
bzero(&(local_addr.sin_zero),8);
if(-1 == bind(sock_fd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in)))
return 0;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons((unsigned short)port);
server_addr.sin_addr = lgxsocket_gethost(hostname);
bzero(&(server_addr.sin_zero),8);
if(connect(sock_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) == -1)
return 0;
return(sock_fd);
}
int lgxsocket_tcpclient_devconnect(char *devname, char *hostname, int port)
{
struct ifreq ifr;
struct sockaddr_in * sin = (struct sockaddr_in *)&ifr.ifr_addr;
int sock_fd;
if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) return 0;
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));
if(ioctl(sock_fd, SIOCGIFADDR,&ifr))
{
close(sock_fd);
return 0;
}
return lgxsocket_tcpclient_srcipconnect(inet_ntoa(sin->sin_addr), hostname, port);
}
int lgxsocket_send(int net_fd, void *data, int length, int flags)
{
int sent, total = 0;
while (total < length)
{
sent = send(net_fd, data + total, length - total, flags);
if (sent <= 0)
{
printf("lgxsocket_send(): send error\n");
return(0);
}
total += sent;
}
return(total);
}
int lgxsocket_recv(int net_fd, void *data, int length ,int flags)
{
int rcvd, total = 0;
while (length > total)
{
rcvd = recv(net_fd, data + total, length - total, flags);
if (rcvd <= 0)
{
printf("lgxsocket_recv(): recv error.\n");
return (0);
}
total += rcvd;
}
return (total);
}
int main(int argc, char **argv)
{
int sockfd;
char *httpreq="GET /dc/0711/AddPoll.aspx?PollId=1121 HTTP/1.1\r\nAccept: */*\r\nReferer: : zh-cn\r\nAccept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)\r\nHost: : Keep-Alive\r\nCookie: ASPSESSIONIDSADRTSTQ=EHBGIFBDDBLKOKNPIAKAMFAJ; bandaotongji=yes\r\n\r\n";
char recvbuf[1024];
int s, i, ret;
char *devn, ethn[16];
if(argc != 4)
{
fprintf(stderr, "usage: %s \n", argv[0]);
return 1;
}
devn = strdup(argv[1]);
s = atoi(argv[2]);
i = atoi(argv[3]);
fprintf(stderr, "open dev: %s:%d - %d\n", devn, s, i);
for(; s <= i; s++)
{
sprintf(ethn, "%s:%d", devn, s);
fprintf(stderr, "connect from %s\n", ethn);
sockfd = lgxsocket_tcpclient_devconnect(ethn, "218.58.75.119", 80);
if(sockfd <= 0)
{
fprintf(stderr, "connect error\n");
return 1;
}
if(!lgxsocket_send(sockfd, httpreq, strlen(httpreq), 0))
{
fprintf(stderr, "send error\n");
return 1;
}
if((ret = recv(sockfd, recvbuf, 1023, 0)) > 0)
{
recvbuf[ret] = 0;
fprintf(stderr, "%s\n", recvbuf);
}
close(sockfd);
sleep(1);
}
return 0;
}