【C++】 网络编程 01

趁着计算机网络这门课布置了课程设计,学习下网络编程。

系统: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以上完成了三个基本操作:
  1. 创建套接字
  2. 建立与服务器的连接
  3. 发送和接收信息
【Over】

时间: 2025-01-11 07:07:34

【C++】 网络编程 01的相关文章

从零探索Java网络编程01之 TCP/IP 与 Socket

最近完成了几项比较简单的项目, 日子有些松散, 终于是在996里偷了点闲暇时光, 想着来研究研究些啥吧?  一个普通的控制台日志映入了我的眼帘(孽缘呀): (图中使用 SpringBoot 的 log4j 来输出日志, logginglevel: debug, jdk版本为1.8) 造成这种现象的原因可能是, Mybatis在执行接口方法时, 实例化了多个Preparedstatement, 启用了不同的NIO线程, 但是其中, 咦?! 没错, NIO中出了一段IO!!! (天哪!), 在查询网

python 网络编程01

一.理解TCP基础 1.寻址 TCP要能识别远程的机器,基于TCP/IP网络的每台机器都有一个唯一的IP地址.(ip) TCP需要知道与远程机器上运行的哪个程序通信,每个程序要使用一个唯一的端口号.(port) 因此,每个TCP连接的端点是由一个IP地址和一个端口号来唯一标识.(ip:port) 虽然有IP和端口号,TCP就能很好的工作,但是记住一串数字比较困难,由于这个原因出现了DNS. 现在想要和远程机器建立连接,可以申请连接该机器IP地址相对应的DNS(如:www.baidu.com),

网络编程01

//服务端 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; namespace learn { class Program { const int portNo = 500; static void Main(string[] args) { IPAddress localAdd = I

Linux高级网络编程系列教程

一.网络应用层编程 1.Linux网络编程01--网络协议入门 2.Linux网络编程02--无连接和面向连接的区别 3.Linux网络编程03--字节序和地址转换 4.Linux网络编程04--套接字 5.Linux网络编程05--C/S与B/S架构的区别 6.Linux网络编程06--UDP协议编程 7.Linux网络编程07--广播(即将更新) 8.Linux网络编程08--多播 9.Linux网络编程09--TCP编程(即将更新) 10.Linux网络编程10--并发服务器(即将更新)

【网络编程】 -- 2019-08-08 18:01:52

原文: http://106.13.73.98/__/1/ 目录 1.socket层 2.理解socket 3.套接字的发展史 4.网络基础 5.socket基本操作 6.socket进阶 7.黏包 8.解决黏包 8.socket的更多方法 1.socket层 ![在这里插入图片描述](http://106.13.73.98/media/ai/2019-03/5ccf086a-baa7-4268-a9f9-a50fb74136b7.png) 2.理解socket socket是应用层与TCP/I

Java学习之网络编程实例

转自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616413.html 多谢分享 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在学习网络编程以前,很多初学者可能觉得网络编程是比较复杂的系统工程,需要了解很多和网络相关的基础知识,其实这些都不是很必需的.首先来问一个问题:你 会打手机吗?很多人可能说肯定会啊,不就是按按电话号码

网络编程学习小结

几种网络编程方式: ISAPI.CGI.WinInet.Winsock 它们之间的差别: 1)  ISAPI主要是开发基于浏览器client与server端程序.效率比CGI方式高,并且也扩展了CGI没有的一些功能.(基于TCP/IP模型中的应用层) 2)  CGI主要是开发基于浏览器client与server端程序.(基于TCP/IP模型中的应用层) 3)  WinInet主要是开发client程序.(基于TCP/IP模型中的应用层) 4)  Winsock主要是基于socket来开发clie

扯谈网络编程之自己实现ping

ping是基于ICMP(Internet Control Message Protocol)协议实现的,而ICMP协议是在IP层实现的. ping实际上是发起者发送一个Echo Request(type = 8)的,远程主机回应一个Echo Reply(type = 0)的过程. 为什么用ping不能测试某一个端口 刚开始接触网络的时候,可能很多人都有疑问,怎么用ping来测试远程主机的某个特定端口? 其实如果看下ICMP协议,就可以发现ICMP里根本没有端口这个概念,也就根本无法实现测试某一个

java网络编程socket\server\TCP笔记(转)

java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅 1 TCP的开销 a  连接协商三次握手,c->syn->s,s->syn ack->c, c->ack->s b  关闭协商四次握手,c->fin->s, s->ack-c,s->fin->c,c->ack->s c  保持数据有序,响应确认等计算开销 d