c++笔记5

来源:互联网 发布:爱奇艺网络异常101 编辑:程序博客网 时间:2024/06/08 06:47

复习昨天:
看看昨天的笔记 (无内容
)

==================================================================================================
UC
第五天

==================================================================================================
(1)  
网络编程
------------------------------
用到scoket(套接字接口): (API)
通用地址
:
#include <sys/socket.h>
uint8_t sa_len; //
可能没有

sa_famlily_t sa_family: //
一定有. 4: AF(PF)_INET /IPV6: AF(PF)_INET6 //是一个地址家族.(地址家族.)
char sa_data[1 4]; //
-----------------------
sturct

演示
:
htons(
短整数
) nto
htonl(
长整型
)
----------------------------
int inet_pton(int family,const char*,void* addrptr )
地址家族,点分十进制,存放转换结果地址
.
int inet_ntop(int family,const void* addrptr,char* strptr,size_t len)//
地址家族,内部格式所在的地址,存放转换结果地址. 地方的大小

------------------------
两个函数的演示程序:
#include <iostream>
using namespace std;
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
                                                                                                   
int main()
{
       const char* str="192.168.0.23";
       long a;
       in_addr ia;
       inet_pton(AF_INET,str,&ia);   //char
型到 in_addr_t  型转换.(内部格式 一种整型变量
.)
       unsigned char* p=NULL;    
       p=(unsigned char*)&ia;
       for(int i=0;i<sizeof(ia);i++){
               cout<<hex<<(int)*p++<<" ";
       }
       cout<<endl;
       char ip[16];
       inet_ntop(AF_INET,&ia,ip,16); //in_addr_t
型转换成char .( 内部格式转换成,点分时进制格式
.)
       cout<<ip<<endl;
      return 0;
}
结果
:
c0 a8 0 17
192.168.0.23
----------------------
(1).
添加,命令行支持

//0--1024
有专门的用途.
//1024--65535
的可以随便用
.
(2).
网络操作
.
1.
建立一个套接字//整数: 要求稳定的联接因此用 TCP 而不用
UDP
2.
绑定 //需要绑定IP ,因为一个机器可能有多个IP 地址

3.
转入监听转态.
4.
通信
.
                                                                                                                                   
#include <iostream>
using namespace std;
#include <sys/socket.h>
#include <netinet/in.h>
#include <apra/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
                                                                                                                                                                     
int main(int argc,char* argv[])
{
   if(argc!=2){
       cout<<*argv<<"port"<<endl;
       return 0;
   }
   short port=atoi(argv[1]);   //
转换端口号
.
                                                                                                                                                                     
   int s=socket(AF_INET,SOCK_STREAM,0); //1.
建立一个套接字(整数)//要求稳定的联接因此用 TCP 而不用
UDP
   if(s<0){
       perror("socket");
       return -1;
   }
                                                                                                                                                                     
   socketaddr_in sin;
   sin.sin_family=AF_INET;
   sin.sin_port=htons(port);  //
本地的short型变量转换成网络格式的short
.
   sin.sin_addr=INADDR_ANY; //
,本机上的任何IP 地址
.
                                                                                                                                                                     
   socklen_t len=sizeof(sin);  //
计算绑定的SOCKETADDR_INT 结果变量的长度.是一个socketlen_t 型的变量
.
   int r;  //
一个临时变量
.
   r=bind(s,(sockaddr*)&sin,len);  //
把这个结构变量绑定到这个套接字上
.
   if(r<0){
       perror("bind");  //
判断是否成功
.
       return -1;
   }
                                                                                                                                                                     
   r=listen(s,20); //
此时的套接字成为被动套接字
.                                        
                                                                                                                           
//
需要直到客户的IP ,和他的端口
.
socketaddr_in clt;
for(;;){
len=sizeof(clt);
r=accep(s,(sockaddr*)&clt,&len); //
因为对方可能是IPV4,IPV6, 因此要len的地址 接收对方的套接地址的长度
..

//accetp()
返回是一个可以和对方通信的新套接字
.
if(r<0){
perror("accepte");
continue;
}
// 4.
通信
.
int cs=r; //
用新的套接字和对方通信
.
//
显示一下对方的消息
.
char ip[16];
inet_ntop(AF_INET,&clt.sin_addr,&ip,16);  //
把内部格式转换成点分十进制格式
.
cout<<ip<<"visited"<<endl;

char msg[100];
sprintf(msg,"your ip:%s/n",ip);  //
输出对方的IP地址
.
write(cs,msg,strlen(ip)+1);
close(cs); //
关闭分机
.
}
return 0;
}

-------------------------------------
1
个断开端口之后2分钟之后才能重新使用.//防止误传的数据包
.
int on=1;
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

=============================================================================
写客户端

======================

#include <iostream>
using namespace std;
#include <unistd.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet.h>
#include <arpa/inet.h>
#include <stdio.h>
                                                                                                   
int main(int argc,char* argv[])
{
if(argc!=3){
cout<<*argv<<"ip port/n";
return 0;
}
short port=atoi(argv[2]);

int s=socket(AF_INET,SOCK_STREAM,0);
IF(S<){
perro("socket");
return -1;
}
sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(post);
inet_pton(AF_INET,ARGV[1],&sin.sin_addr);
int r;
len=sizof(sin);
r=connect(s,(sockaddr*)&sin,len);
if(r<0){
perror("connect");
reuturn -1;
}
char msg[100];
int bytes=read(s,msg,100); //
返回读到的字节数
if(types<0){
perror("read");
return -1;
}
if(byte==0){
cout<<"connection lost"<<endl;
}
cout<<msg<<endl;
close(s);
   return 0;
                                                                                                   
}
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
TCP
服务器程序
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
基本步骤:
(1).
添加,命令行支持

//0--1024
有专门的用途.
//1024--65535
的可以随便用
.
(2).
网络操作
.
1.
建立一个套接字//整数: 要求稳定的联接
TCP,3
2.
绑定 //需要绑定IP ,因为一个机器可能有多个IP 地址

3.
转入监听转态
4.
通信.
实现程序
:
-----------------------------------------
    #include <iostream>
    using namespace std;
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <set>
    #include <signal.h>
    #include <sys/wait.h>

    void func(int singno)
    {
        signal(singno,func);
        wait(NULL);//
释放子进程的资源,以免产生僵死进程
.
    }
 
   int main(int argc ,char* argv[])
   {
       if(argc!=2)
       {
           cout << argv[0] << " Port!" << endl;
           return 0;
       }
       set<in_addr_t>si;  //
为了防止重复登录,要用一个set  型的变量
.
       short port =atoi(argv[1]);
       
       int s=socket(AF_INET,SOCK_STREAM,0);//
建立套接字
.
       if(s<0)
       {
           perror("socket");
           return -1;
       }
        sockaddr_in sin;//
创建结构变量
.
        sin.sin_family=AF_INET;//
指定地址的协议类型.AF_INETIPv4,AF_INET6
IPv6.
      sin.sin_port=htons(port);
      sin.sin_addr.s_addr=INADDR_ANY;//
保存主机的IP地址,由于主机可以有多个网卡可以用INADDR_ANY表示本机的任意的IP地址
.
       socklen_t len=sizeof(sin); //
取得地址结构的长度
.
       int r;
      r=bind(s,(sockaddr*)&sin,len);//
绑定,在这要将sin强制转为sockaddr*指针型//因为绑定函数第二个参数要一个sockaddr型的指针变量
.
       if(r<0)
      {
            perror("bind");
           return 0;
       }
      r=listen(s,20);  //
将主动套接口转换成被动套接口.( 只有被动套接口才能接受客户端的联接请求
.)
      if(r<0)
      {
           perror("listen");
          return 0;
       }
      sockaddr_in clt;//
创建新的地址结构,以便能与客户端进行交流
.
     for(;
      {
           len =sizeof(clt);
           r=accept(s,(sockaddr*)&clt,&len);//
使分机进入监听状态.(该函数是一个阻塞函数,直到一个客户向他发送请求
)
          if(r<0)
           {
              perror("accept");
              continue;
           }
           int cs=r;
           signal(SIGCHLD,func);//
捕获SIGCHLD以免产生僵死进程
.
          if(fork()!=0)
           {
               close(cs);
              continue;//
使得父进程能够继续监听,顺便释放不该占用的资源
.
          }
         close(s);//
释放子进程不该占用的资源
.
          char ip[16];
            inet_ntop(AF_INET,&clt.sin_addr,ip,16);//
IP地址转为机器能支持的数值格式
.
          cout << ip << " visited." << endl;
           char msg[100];
          for(;
          {
             r=read(cs,msg,99);//
接收消息
.
             if(r<0)
              {
                  perror("read");
                  exit(-1);
               }
            else if(r==0)
             {
                  cout << "disconnect " << ip << endl;
                 exit(0);
              }
            msg[r]='/0';
            cout << ip << ':' << msg << endl;
             write(cs,&msg,strlen(msg)+1);//
发送消息
.
        }
         close(cs);//
关闭相应套接字
.
          exit(0);//
相应进程退出
.
      }
       return 0;
 }
客户端代码
:
     #include <iostream>
     using namespace std;
    #include <unistd.h>
    #include <fcntl.h>
     #include <netinet/in.h>
     #include <sys/socket.h>
     #include <arpa/inet.h>
     #include <stdio.h>
   
    int main(int argc,char* argv[])
    {
        if(argc!=3)
        {
            cout << argv[0] << " IP Port!" << endl;
            return 0;
        }
        short port=atoi(argv[2]);  //
获得端口号
.
        int s=socket(AF_INET,SOCK_STREAM,0);  //
创建套接字
.
        if(s<0)
       {
            perror("Socket");
            return -1;
        }
        sockaddr_in sin; //
创建socketaddr型的结构变量
.
        sin.sin_family=AF_INET; //
指定地址的家族类型
,IPV4
        sin.sin_port=htons(port);  //
将主机的存储格式转换成网络的存储格式.以便应用能够正常运行
.
        inet_pton(AF_INET,argv[1],&sin.sin_addr);  //
将点分十进制的IP 地址转换成内部格式的
.
        socklen_t len=sizeof(sin);   //
取得sin结构变量的长度
.
        int r=connect(s,(sockaddr*)&sin,len);  //
和服务器建立连接
.
        if(r<0)
        {
            perror("connect");
            return -1;
        }
        char msg[100];
        for(;
        {
            cout << "Input message:";
            cin.getline(msg,100);
            if(!strcmp(msg,"bye"))
                break;
            cin.clear();
            write(s,msg,100);//
发送消息,s的本质是一个文件描述符,可以像操作UNIX文件一样来操作
.
            int bytes=read(s,msg,100);//
从文件中读信息,(接收消息
)
            if(bytes<0)
            {
                perror("read");
                return -1;
            }
            if(bytes==0)
            {
                cout << "connection lost!" << endl;
            }
            cout << msg << endl;
        }
        close(s);//
关闭套接字
.
        return 0;
    }

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
UDP
不稳定的联接: (速度快) TCP UDP 可以用相同的端口号
.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
UDP ;
为了高效率的传数据,放弃了TCP的稳定联接,来达到高效率
.
演示程序

---------------------------------
#include <iostream>
using namespace std;
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
                                                                                                   
int main(int argc,char* argv[])
{
if(argc!=2){
cout<<*argv<<"port"<<endl;
return -1;
}
short port=atoi(argv[1]);

int s=socket(AF_INET,SOCK_DGRAM,0);
if(s<0){
perror("soket");
return -1;
}

sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(port);
sin.sin_addr.s_addr=INADDR_ANY;

socklen_t len=sizeof(sin);
r=bind(s,(sockaddr*)&sin,len);
if(r<0){
perror("bind");
return -1;
}

for(;;){
char cmd;
cout<<"r/s ip port msg/b msg/q"<<endl;
char ip[100];
char msg[500];
cin>>cmd;
if(cmd=='q'){
break;
}
switch(cmd){
case 'r':
len=sizeof(sin);
r=recvfrom(s,msg,499,0,(sockaddr*)&sin,&len);
if(r<0){
perror("recvfrom");
continue;
}
break;
inet_ntop(AF_INET,sin.sin_addr,ip,sizeof(ip));
port=ntohs(sin.sin_port);
msg[r]='/0';
cout<<ip<<":"<<port<<' '<<msg<<endl;
break;
case 'b':
cin.getline(msg,sizeof(msg));
cin.clear();
sendto(s,msg,strlen(msg),0,(sockaddr*)&sin,sizeof(sin));
break;
case 's':
cin>>ip>>port;
cin.geline(msg,sizeof(msg));
sin.sin_famlily=AF_INET;
inet_pton(AF_INET,ip,&sin.sin_addr);
sendto(s,msg,strlen(len),0,(sockaddr*)&sin,sizeof(sin));
defaut:
cout<<"invalid command/n";
cin.ignore(1000,'/n');
}
close(s);
return 0;
}


   return 0;
                                                                                                   
}
===========================================

 

 
原创粉丝点击