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;
}
结果:
c
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_INET为IPv4,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;
}
===========================================
- <<Effective C++>>笔记5
- c学习笔记(5)
- C++plus笔记5
- C复习笔记(5)-6.23
- C语言学习笔记(5)
- C语言学习笔记5
- C语言学习笔记5
- C语言学习笔记5
- C++Primer学习笔记《5》
- C语言笔记整理5
- C语言笔记(5)
- C语言学习笔记5
- C语言复习笔记 5
- C - 笔记
- c笔记
- c笔记
- C 笔记
- c 笔记
- c++笔记3
- 到期走人但服务期未满算违约吗?
- c++笔记4
- asp.net如何取得纯客户端控件的值
- 必须知道的SQL[转]
- c++笔记5
- 深信服2008校园招聘笔试题
- 基于windows系统的智能DNS
- C++ sizeof 使用规则及陷阱分析
- 解决Boost.Regex对中文支持不好的问题
- DFGGR
- FGGRTYYJHG
- 用java实现文件的拷贝
- 18种根据屏幕字段找数据表的方法 rev1.1