美文网首页
C++ socket网络编程

C++ socket网络编程

作者: 朋小谅ya | 来源:发表于2020-05-27 17:52 被阅读0次

Socket介绍:

socket即套接字,端口号拼接到IP地址就构成了套接字。如果IP地址是169.254.24,而端口号是3000,那么得到套接字就是(169.254.24:3000),即(主机IP地址:端口号)。
三种不同类型的套接字:
1、 (SOCK-STREAM)流式套接字:提供一种可靠的、面向连接的双向数据传输服务,实现了数据无差错、无重复的发送。发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
2、 (SOCK-DGRAM)数据报套接字: 提供一种无连接、不可靠的双向数据传输服务。数据包以独立的形式被发送,数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字。
3、(SOCK-RAW)原始套接字:该套接字允许对较低层协议(如IP或ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。

客户端/服务端模式:

网络架构使用客户端(Client)-服务器(Server)模式(简称C/S),即客户端向服务器发出请求,服务器接收请求后,提供相应的服务。
服务端:建立socket,声明自身的端口号和地址并绑定到socket,使用listen打开监听,然后不断用accept去查看是否有连接,如果有,捕获socket,并通过recv获取消息的内容,通信完成后调用closeSocket关闭这个对应accept到的socket,如果不再需要等待任何客户端连接,那么用closeSocket关闭掉自身的socket。
客户端:建立socket,通过端口号和地址确定目标服务器,使用Connect连接到服务器,send发送消息,等待处理,通信完成后调用closeSocket关闭socket。

TCP编程步骤:

一、服务端

1、加载套接字库,创建套接字(WSAStartup()/socket());
2、绑定套接字到一个IP地址和一个端口上(bind());
3、将套接字设置为监听模式等待连接请求(listen());
4、请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());
5、用返回的套接字和客户端进行通信(send()/recv());
6、返回,等待另一个连接请求;
7、关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup());

二、客户端

1、加载套接字库,创建套接字(WSAStartup()/socket());
2、向服务器发出连接请求(connect());
3、和服务器进行通信(send()/recv());
4、关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup());

TCP服务端代码

#include "pch.h"
#include <iostream> 
#include <winsock2.h>  
 
#pragma comment(lib,"ws2_32.lib")  
using namespace std;
 
int main(int argc, char* argv[])
{
    //初始化WSA  
    WORD sockVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    if (WSAStartup(sockVersion, &wsaData) != 0)
    {
        return 0;
    }
 
    //创建套接字  
    SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (slisten == INVALID_SOCKET)
    {
        cout << "create socket error !" << endl;
        return 0;
    }
 
    //绑定IP和端口  
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(8888);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
    {
        cout << "bind error !" << endl;
    }
 
    //开始监听  
    if (listen(slisten, 5) == SOCKET_ERROR)
    {
        cout << "listen error !" << endl;
        return 0;
    }
 
    //循环接收数据  
    SOCKET sClient;
    sockaddr_in remoteAddr;
    int nAddrlen = sizeof(remoteAddr);
    char revData[255];
    while (true)
    {
        cout << "阻塞。。。。等待连接。。。" << endl;
        sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
        if (sClient == INVALID_SOCKET)
        {
            cout << "accept error !" << endl;
            continue;
        }
 
        cout << "接受到一个连接:" << inet_ntoa(remoteAddr.sin_addr) << endl;
 
        //接收数据  
        int ret = recv(sClient, revData, 255, 0);
        if (ret > 0)
        {
            revData[ret] = 0x00;
            printf(revData);
        }
 
        //发送数据  
        const char * sendData = "你好,TCP客户端!\n";
        send(sClient, sendData, strlen(sendData), 0);
        closesocket(sClient);
    }
 
    closesocket(slisten);
    WSACleanup();
    return 0;
}

TCP客户端代码

#include "stdafx.h"
#include<winsock2.h>
#include<iostream>
#include<string>
 
using namespace std;
#pragma comment(lib, "ws2_32.lib")
 
int main()
{
    WORD sockVersion = MAKEWORD(2, 2);
    WSADATA data;
    if (WSAStartup(sockVersion, &data) != 0)
    {
        return 0;
    }
 
    while (true) 
    {
        SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sclient == INVALID_SOCKET)
        {
            cout << "invalid socket!" << endl;
            return 0;
        }
 
        sockaddr_in serAddr;
        serAddr.sin_family = AF_INET;
        serAddr.sin_port = htons(8888);
        serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
        if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
        {  
            //连接失败 
            cout << "connect error !" << endl;
            closesocket(sclient);
            return 0;
        }
 
        string data;
        cin >> data;
        const char * sendData;
        sendData = data.c_str();   //string转const char* 
                                   
        /*
        send()用来将数据由指定的socket传给对方主机
        int send(int s, const void * msg, int len, unsigned int flags)
            s为已建立好连接的socket,msg指向数据内容,len则为数据长度,参数flags一般设0
            成功则返回实际传送出去的字符数,失败返回-1,错误原因存于error
        */
        send(sclient, sendData, strlen(sendData), 0);
        
        char recData[255];
        int ret = recv(sclient, recData, 255, 0);
        if (ret>0)
        {
            recData[ret] = 0x00;
            cout << recData << endl;
        }
        closesocket(sclient);
    }
 
    WSACleanup();
 
    system("pause");
    return 0;
}

相关文章

  • 网络编程

    Linux Socket编程(不限Linux) C/C++ socket编程教程:1天玩转socket通信技术 一...

  • 许世伟的Go语言基础 第五章总结

    第5章 网络编程 5.1 socket编程 以往socket编程: 建立socket:使用socket()函数。 ...

  • 网络编程

    python学习笔记-网络编程 socket编程: socket()函数:socket.socket([famil...

  • C++ socket网络编程

    Socket介绍:socket即套接字,端口号拼接到IP地址就构成了套接字。如果IP地址是169.254.24,而...

  • 网络编程

    网络 Socket 基于TCP协议的Socket编程 基于UDP协议的Socket编程

  • 2018-09-12 day18-网络编程和http请求

    网络编程 socket 网络编程就是socket编程,socket就是套接字,就是进行数据通信的两端(服务器和客户...

  • Linux_socket编程入门(C++)

    Linux_socket编程入门(C++) 参考资料 参考:这里,还有这里 实现思路 Socket编程主要分为两部...

  • 网络基础介绍

    网络编程的两种 TCP socket编程,是网络编程的主流。之所以叫Tcp socket编程,是因为底层是基于Tc...

  • Go语言的Socket编程

    我们在日常开发当中,几乎所有网络编程都是Socket编程,因为大部分底层网络的编程都离不开Socket编程。 什么...

  • 动脑学院架构篇-Java Socket编程基础及深入讲解

    【Socket】Java Socket编程基础及深入讲解 Socket是Java网络编程的基础,了解还是有好处的,...

网友评论

      本文标题:C++ socket网络编程

      本文链接:https://www.haomeiwen.com/subject/oozwahtx.html