您的位置:首页 > 理论基础 > 计算机网络

【C++】 网络编程 01

2016-06-11 05:12 316 查看
趁着计算机网络这门课布置了课程设计,学习下网络编程。

系统:Ubuntu 14.01...

1. 关于Socket(套接字)

1.1

套接字是存在于运输层和应用层间的抽象层,通过它来区分不同应用程序进程间的网络通信和连接。

其主要包含3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。

1.2

套接字的通信流程:



1.3

socket()函数:

int socket(int domain, int type, int protocol);


其中:

domain为创建的套接字指定协议集。

AF_INET 表示IPv4网络协议

AF_INET6 表示IPv6网络协议

AF_UNIX 表示本地套接字

type 如下:

SOCK_STREAM
(可靠的面向流服务或流套接字)

SOCK_DGRAM
(数据报文服务或者数据报文套接字)

SOCK_SEQPACKET
(可靠的连续数据包服务)

SOCK_RAW
(在网络层之上的原始协议)

protocol 指定实际使用的传输协议。 如果该项为“
0
”的话,即根据选定的domain和type选择使用缺省协议。(目前也只遇到了0)

connection()函数:

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);


socket即socket()函数返回值

myaddr 表示指向sockaddr结构(用于表示所分配地址)的指针

addrlen表示sockaddr结构的长度

当返回值为-1,表示出错;返回0表示连接成功。

先编写客户端程序client.cpp,创建一个套接字:

#include<iostream>
#include<sys/socket.h>
using namespace std;

int main()
{
int socket_desc;
socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)
{
cout<<("Could not create socket");
}

return 0;
}


1.4

接下来将这个套接字连接到Server上,需要ip地址和端口号

使用sockaddr_in对需要连接到的服务器进行设定,sockaddr_in和sockaddr结构:

// IPv4 AF_INET sockets:
struct sockaddr_in {
short            sin_family;   // e.g. AF_INET, AF_INET6
unsigned short   sin_port;     // e.g. htons(3490)
struct in_addr   sin_addr;     // see struct in_addr, below
char             sin_zero[8];  // zero this if you want to
};

struct in_addr {
unsigned long s_addr;          // load with inet_pton()
};

struct sockaddr {
unsigned short    sa_family;    // address family, AF_xxx
char              sa_data[14];  // 14 bytes of protocol address
};


尝试连接到baidu.com的服务器,ip:14.215.177.37,ip地址是256进制的4字节数据,如14.215.177.37(baidu.com),用inet_addr函数将它转化成长整数类型:

server.sin_addr.s_addr = inet_addr("14.215.177.37"); 


向上述代码添加sockaddr_in结构体对象server:

#include<iostream>
#include<sys/socket.h>
#include<arpa/inet.h>

using namespace std;

int main()
{
int socket_desc;
struct sockaddr_in server;  

//create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if(socket_desc == -1)
{
cout<<"Could not creat socket"<<endl;
}

server.sin_addr.s_addr = inet_addr("14.215.177.37");
server.sin_family = AF_INET;
server.sin_port = htons(80);

//connect to remote server
if(connect(socket_desc, (struct sockaddr*)&server, sizeof(server))<0)
{
cout<<("connect error")<<endl;
return 1;
}

cout<<("Connected")<<endl;

return 0;
}


如果无误,运行后控制台会显示"Connected",连接成功

tips:Connections are present only in tcp sockets

1.5

用send()函数实现通过Socket发送数据

send()函数:

int send(int socket, const void * buff, int length, int flags);


recv()函数:

int recv(int socket, void *buff, int length, int flags);


*buff是指向待传输数据buffer的指针

length是待传输数据的长度

flags标志调用方式,一般置0(?)

向baidu的服务器发送请求并获取回复:

#include<iostream>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

using namespace std;

int main()
{
int socket_desc;
struct sockaddr_in server;
char *msg, server_reply[2000];

//create socket
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
if(socket_desc == -1)
{
cout<<"Could not creat socket"<<endl;
}

server.sin_addr.s_addr = inet_addr("64.233.187.105");
server.sin_family = AF_INET;
server.sin_port = htons(80);

//connect to remote server
if(connect(socket_desc, (struct sockaddr*)&server, sizeof(server))<0)
{
cout<<("connect error")<<endl;
return 1;
}

cout<<("Connected")<<endl;

//send data
msg = "GET / HTTP/1.1\r\n\r\n";     //    HTTP Request
if(send(socket_desc, msg, strlen(msg), 0)<0)
{
cout<<"Send failed"<<endl;
return 1;
}
cout<<"Data send\n"<<endl;

//Recieve a reply from the server
if(recv(socket_desc, server_reply, 2000, 0)<0)
{
cout<<"Recv failed"<<endl;
}
cout<<"Reply revieved\n"<<endl;
cout<<server_reply<<endl;

return 0;
}


其中 "GET / HTTP/1.1" 是HTTP请求...具体什么意思暂时并不明白,但可以验证发送成功
返回如下信息:


Connected
Data send

Reply revieved

HTTP/1.1 302 Moved Temporarily
Date: Fri, 10 Jun 2016 21:01:45 GMT
Content-Type: text/html
Content-Length: 215
Connection: Keep-Alive
Location: http://www.baidu.com/search/error.html Server: BWS/1.1
X-UA-Compatible: IE=Edge,chrome=1
BDPAGETYPE: 3
Set-Cookie: BDSVRTM=0; path=/


1.6
最后关闭socket,用unistd.h中的close()函数:


close(socket_desc);


1.7
以上完成了三个基本操作:


创建套接字

建立与服务器的连接

发送和接收信息

【Over】


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: