memcached限制ip进行tcp连接

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mzlly999/article/details/83973799

最近新增了一台服务器,想把apache那台的memcached分到这台新机器上,我杯具的有个错误认识:

我以为memcached -l 的listen参数是用来监听哪台机进行connection,比如apache的ip是10.0.0.1,memcached那台服务器的ip是10.0.0.2,开始我以为,如果只让memcached允许来自apache机器的connection,只要配置memcached -l 10.0.0.1就可以了,可是这样报错:

bind(): Cannot assign requested address
failed to listen

问题是-l参数就是绑定本机网卡的,根本不是来限制tcp的connection的,这个限制是要靠iptable来搞的。

先说下-l绑定本机网卡的问题,当使用-l 127.0.0.1运行md的时候,只有本机能connect上这个memcache;让使用-l 10.0.0.2运行的时候(这里假定10.0.0.2是md机器对外的ip),任何机器都可以连上这个memcache。同事有人指出,-l实际上就是在指定绑定机器的那个网卡的问题,比如当使用ifconfig的时候,显示信息类似如下:

eth0      Link encap:Ethernet  HWaddr 00:17:a4:3a:e8:56

inet addr:10.0.0.2  Bcast:10.0.0.255  Mask:255.255.255.0

inet6 addr: fe80::217:a4ff:fe3a:e856/64 Scope:Link

UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

RX packets:1635820 errors:0 dropped:0 overruns:0 frame:0

TX packets:20283 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

RX bytes:148717543 (141.8 MiB)  TX bytes:2281514 (2.1 MiB)

Interrupt:25

lo        Link encap:Local Loopback

inet addr:127.0.0.1  Mask:255.0.0.0

inet6 addr: ::1/128 Scope:Host

UP LOOPBACK RUNNING  MTU:16436  Metric:1

RX packets:17 errors:0 dropped:0 overruns:0 frame:0

TX packets:17 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:0

RX bytes:1526 (1.4 KiB)  TX bytes:1526 (1.4 KiB)

这样当使用-l 127.0.0.1的参数跑的时候是绑定lo,监听来自lo的连接,这样只有本机能connect,;当使用-l 10.0.0.2的参数跑的时候是绑定eth0(对外ip),这样外面的任何机器都能connect。
当使用-l制定对外ip的时候,肯定不希望任何机器都能连接上我们服务器的memcached,希望只要指定ip的机器能连上memcached,比如这个例子中的apache(ip:10.0.0.1)和memcached本机(10.0.0.2),这个时候就是需要iptables的时候,先写一个规则文件iptable-rules,类似如下(这里假定11211是memcached跑的端口):
=============
*filter
-A INPUT -i lo -j ACCEPT
#38049
-A INPUT -p tcp -m tcp –dport 11211 -s 10.0.0.1 -j ACCEPT
-A INPUT -p tcp -m tcp –dport 11211 -s 10.0.0.2 -j ACCEPT
-A INPUT -p tcp -m tcp –dport 11211 -j REJECT
COMMIT
=============
然后使用命令iptables-restore < iptable-rules 应用这些规则。成功后使用iptables -L 可以看到对端口的限制已经生效
展开阅读全文

建立TCP/IP连接

05-21

刚接触这部分内容 照着书做的 大致了解了一下 但是程序运行的时候服务器端始终无法收到用户端的请求 劳烦老手帮忙看一下 稍加讲解.... 感谢!rnrn这是用户端rn[code=C/C++]rn#pragma comment(lib,"wsock32.lib")rn#include rn#include rnrnunsigned short port;rnchar *hostname;rnrnint initsockets();rnvoid getargument(int argc,char** argv);rnvoid errorprint(char* x);rnvoid userhelp();rnrnint main(int argc,char** argv)rnrn SOCKET clientfd;rn int err;rn struct sockaddr_in serveraddr;rn struct hostent* ptrhost;rn char response[4096];rn char *msg="HELLO SERVER";rn if(argc!=3)rn rn userhelp();rn return 1;rn rnrn getargument(argc,argv);rnrn initsockets();rnrn //创建套接字rn clientfd=socket(AF_INET,SOCK_STREAM,0);rnrn //创建失败rn if(clientfd==INVALID_SOCKET)rn rn errorprint("no more socket resources");rn return 1;rn rnrn //解析地址rn if(atoi(hostname))rn rn u_long ip_addr=inet_addr(hostname);rn ptrhost=gethostbyaddr((char*)&ip_addr,sizeof(u_long),AF_INET);rn rn elsern ptrhost=gethostbyname(hostname);rn if(!ptrhost)rn rn errorprint("cannot resolve hostname");rn return 1;rn rnrn //设置服务器端地址选项rn serveraddr.sin_family=AF_INET;rn //将本机地址复制给服务器端地址rn memcpy((char*)&(serveraddr.sin_addr),ptrhost->h_addr_list,ptrhost->h_length);rnrn serveraddr.sin_port=htons(port);//将一个无符号短整型数值转换为网络字节序,即大端模式(big-endian)rn //连接服务器rn err=connect(clientfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));rnrn //连接失败rn if(err=INVALID_SOCKET)rn rn errorprint("cannot connect to server");rn return 1;rn rn //连接成功后输出信息rn printf("You are connected to the server \n");rn //发送消息到服务器端rn send(clientfd,msg,strlen(msg)+1,0);rn memset(response,0,sizeof(response));rn //接收来自服务器端的消息rn recv(clientfd,msg,strlen(msg)+1,0);rn printf("server says %s\n",response);rn //关闭套接字rn closesocket(clientfd);rn //释放winsocket初始化时占用的资源rn WSACleanup();rn return 0;rnrnint initsockets()rnrn WSADATA wsadata;rn WORD sockversion;rn int err;rnrn sockversion=MAKEWORD(2,2);rnrn err=WSAStartup(sockversion,&wsadata);rnrn if(err!=0)rn rn printf("Error %d : Winsock not available \n", err);rn return 1;rn rn return 0;rnrnvoid getargument(int argc,char**argv)rnrn int i;rn for(i=1;i3)rn port=atoi(&argv[i][3]);rn break;rn case 'h':rn hostname=&argv[i][3];rn break;rn default:rn userhelp();rn break;rn rn rn rn return;rnrnrnvoid errorprint(char * x)rnrn printf("Error %d : %s\n",WSAGetLastError(),x);rnrnrnvoid userhelp()rnrn printf("user help: -h:str -p:int\n");rn printf(" -h:str The Host name \n");rn printf(" -p:int The Port number to use\n");rn ExitProcess(-1);rnrnrnrn[/code]rn// TCP.c.cpp : 定义控制台应用程序的入口点。rn//rn#includern#pragma comment(lib,"wsock32.lib")rn#includernrn#define MAX_SER 10rnrnchar *hostname;rnunsigned short maxservice;rnunsigned short port;rnrnvoid initial();//系统初始化(主机名、最大服务进程数、端口号)rnint initsockets();rnvoid getargments(int argc,char** argv);//获取用户提供的选项rnvoid errorprint(char * x);rnvoid userhelp();rnint loopcontrol(SOCKET listenfd,int ismultitasking);rnvoid service(LPVOID lpv);rnrnrnrnrnrnint main(int argc,char**argv)rnrn SOCKET listenfd;rn int err;rn struct sockaddr_in serveraddr;rn struct hostent *ptrhost;rnrn initial();//初始化系统rnrn getargments(argc,argv);//获取参数rn initsockets();//初始化socketrnrnrn listenfd=socket(AF_INET,SOCK_STREAM,0);//创建TCP流套接字rnrn if(listenfd==INVALID_SOCKET)//如果创建套接字失败rn rn printf("Error: out of socket resources\n");rn return 1;rn rnrn if(atoi(hostname))//如果是IP地址rn rn u_long ip_addr=inet_addr(hostname);//若字符串有效则为32位二进制网络字节序的IPV4地址,否则为INADDR_NONErnrn ptrhost=gethostbyaddr((char*)&ip_addr,sizeof(u_long),AF_INET);//根据IP地址好到与之匹配的主机名rn rn else//如果是主机名rn ptrhost=gethostbyname(hostname);//根据主机名获取hosten的指针rnrn if(!ptrhost) //如果解析失败rn rn errorprint("cannot resolve hostname\n");rn return 1;rn rnrnrn //设置服务器地址rnrn serveraddr.sin_family=AF_INET;//设置地址族为PF——INETrnrn serveraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将一个通配的Internet地址转换成无符号长整形的网络字节序数rnrn serveraddr.sin_port=htons(port);//将端口号转换成无符号断整型的网络字节序数rnrn err=bind(listenfd,(const struct sockaddr*)&serveraddr,sizeof(serveraddr));//将套接字与服务器地址绑定rnrn if(err==INVALID_SOCKET)//如果绑定失败rn rn errorprint("unable to bind socket\n");rn return 1;rn rnrnrn err=listen(listenfd,SOMAXCONN);//开始侦听,设置等待连接的最大队列长度为SOMAXCONN(由系统决定),默认为5个rnrn if(err==INVALID_SOCKET)//如果侦听失败rn rn errorprint("listen failed\n");rn return 1;rn rnrn loopcontrol(listenfd,1);rn printf("Server is down\n");rnrn WSACleanup();//释放Win素材oket初始化时占用的资源rnrn return 0;rnrnvoid initial()rnrn hostname="127.0.0.1";rn maxservice=3;rn port=8088;rnrnvoid getargments(int argc,char** argv)rnrn int i;rn for(i=1;i3)rn port=atoi(&argv[i][3]);rn rn break;rn case 'h'://若为主机名rn hostname=&argv[i][3];rn rn break;rn case 'n'://最多服务次数rn maxservice=atoi(&argv[i][3]);rn printf("maxservice: %d",maxservice);rn break;rn default:rn userhelp();rn break;rn rn rn rn printf("port: %d\n",port);rn printf("hostname: %s\n",hostname);rn printf("maxservice: %d\n",maxservice);rn return;rnrnint initsockets()rnrn WSADATA wsadata;rn WORD sockversion;rn int err;rnrn sockversion=MAKEWORD(2,2);//设置winsock版本号rnrn err=WSAStartup(sockversion,&wsadata);rn if(err!=0)rn rn printf("Error %d :Winsock not available\n",err);rn return 1;rn rn return 0;rnrnvoid errorprint(char * x)rnrn printf("Error %d : %s\n",WSAGetLastError(),x);rnrnint loopcontrol(SOCKET listenfd, int ismultitasking)rnrn SOCKET acceptfd;rn struct sockaddr_in clientaddr;rn int err;rn int nsize;rn int servernum=0;rn HANDLE handles[MAX_SER];rn int myID;rnrn while(servernum 论坛

没有更多推荐了,返回首页