Linux下socket编程基础1-初探(把服务端代码放到云服务器上)
在阿里云服务器运行socket简单的服务端代码
- 昨天初学的socket测试代码是用127.0.0.1电脑本地回环测试的,真的要验证行不行,还得放到云服务器上。connect()失败了半天,先是测试了客户端是否有问题。用连接百度ip和8080端口的方法,发现是可以connect成功 的,所以转而看服务端代码是否有问题。
- 在云服务器上运行服务端代码,开启另一个终端输入命令lsof -i:端口号,查看那个端口号的工作状态,发现那个端口号其实也是正常处于监听状态的,代码似乎并没有错
- 面向百度,折腾了半天,发现云服务器有些知识点还真得需要记录下来。
贴上代码:
Client
void My_client(void){
char buf[128] = {0};
struct iovec buffer={
.iov_base = buf,
.iov_len = sizeof(buf)
};
struct msghdr Mymsg={
.msg_name = nullptr,
.msg_namelen = 0,
.msg_iov = &buffer,
.msg_iovlen = 1,
.msg_control = nullptr,
.msg_controllen = 0,
.msg_flags = 0
};
int Mysocket = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in Server_Addr;
bzero(&Server_Addr,sizeof(Server_Addr));//memset(&Server_Addr,0,sizeof(Server_Addr));
Server_Addr.sin_family=AF_INET;
Server_Addr.sin_addr.s_addr=inet_addr("填入服务器的公网地址"); //强调是公网地址
Server_Addr.sin_port=htons(12345); //要访问的端口,这个是服务端程序决定的
cout << "connect...."<<endl;
int res = connect(Mysocket,(struct sockaddr*)&Server_Addr,sizeof(Server_Addr));
if(res!=-1){//对服务器发送连接请求
cout<<"connect succ"<<endl;
std::cout << "ready accept message"<<endl;
recvmsg(Mysocket,&Mymsg,0); //接收信息
printf("%s\n",Mymsg.msg_iov->iov_base);
std::cout << "read message done"<<endl;
}else{
std::cout<<"connect fail! res :" << res <<endl;
}
system("netstat -an | grep 12345");
close(Mysocket);
}
Server
void My_server(void){
//初始化发送数据缓冲区
char buf[128]={0};
struct iovec buffer={
.iov_base = buf,
.iov_len = sizeof(buf)
};
struct msghdr Mymsg={
.msg_name = nullptr,
.msg_namelen =0,
.msg_iov = &buffer,
.msg_iovlen = 1,
.msg_control = nullptr,
.msg_controllen = 0,
.msg_flags = 0
};
//创建套接字
int Mysocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//将套接字和IP、端口绑定
struct sockaddr_in Server_Addr;
memset(&Server_Addr,0,sizeof(Server_Addr));
Server_Addr.sin_family=AF_INET; //设置使用ipv4地址
Server_Addr.sin_addr.s_addr=inet_addr("云服务器私有地址");//强调私有地址,和公有地址不同的
Server_Addr.sin_port=htons(12345); //设置监听的端口
bind(Mysocket,(struct sockaddr *)&Server_Addr,sizeof(Server_Addr));
//进入监听状态
listen(Mysocket,10);
//接收客户端请求
struct sockaddr_in client_addr;
socklen_t client_size = sizeof(client_addr);
std::cout << "ready to accept!...."<<endl;
int client_sock = accept(Mysocket,(struct sockaddr*)&client_addr,&client_size);//在此阻塞
std::cout << "accept finish!.."<<endl;
//向客户端发送数据
char str[] = "hello,world!";
Mymsg.msg_iov->iov_base = str;
sendmsg(client_sock,&Mymsg,0); //write(client_sock,str,sizeof(str));用write也是可以的
close(client_sock);
- 代码的功能就是客户端连接服务端成功之后,服务端发送一个字符串给客户端,然后各自断开连接,结束程序。
阿里云服务器配置
- 前提是不考虑安全性,毕竟为了解决问题把防火墙关掉了...
- 要注意的几点:
1.阿里云服务器控制台的安全组里开启端口
2.客户端访问的是云服务器的公有ip,服务端监听的是云服务器的私有ip
3.关闭防火墙(实际我前两步都做好了,但是还是连接不上,最后才百度到关闭防火墙,应该有更好的解决办法吧)
- 阿里云服务器关闭防火墙方法
- 首先要有firewall这个命令,没有的话用apt install firewall获取(服务器系统是ubuntu)
- 然后输入命令systemctl stop firewalld即可关闭防火墙