当前位置: 代码迷 >> 综合 >> C++ Socket通信
  详细解决方案

C++ Socket通信

热度:51   发布时间:2024-02-12 03:12:27.0

服务端:

#include <iostream>

#include <thread>

#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

using namespace std;

 

 

int main() {

    //不用管这两行,抄就完事了

    WSADATA ws;

    WSAStartup(MAKEWORD(2, 2), &ws);

    /*

      int family : 协议簇,可选AF_INET/AF_INET6/......

      int type   : 流类型, 可行 SOCK_STREAM/SOCK_DGRAM/SOCKET_RAW...

      int protocol: 给0表示由系统自动根据前两个参数选择协议

      成功返回描述符

      失败返回-1

    */

    int server = socket(AF_INET, SOCK_STREAM, 0);            

    if (server == -1) {

        cout << "创建套接字失败:" << errno << endl;

        exit(0);

    }

    /*

      AF_INET 的地址类型:

      s_addr 表示一个32位地址,可用inet_addr(...)将将字符串转成uint32

      htons 表示转变字节序

    */

    sockaddr_in addr;

    addr.sin_family = AF_INET;

    addr.sin_addr.S_un.S_addr = INADDR_ANY;

    addr.sin_port = htons(8080);

    /*

      int fd

      sockaddr* addr : 表示绑定的端口和本机ip,不设置则由系统随机决定

      socklen_t len  : 表示结构体的大小

      成功返回0

      失败返回-1

      */

    int bindRet = bind(server, (sockaddr*)&addr, sizeof(addr));

    if (bindRet == -1) {

        cout << "绑定端口失败:" << errno << endl;

        exit(0);

    }

    /*

      int fd

      int backlog : 等待连接的客户数量

      成功返回0

      失败返回-1

    */

    int lisRet = listen(server, 100);

    if (lisRet == -1) {

        cout << "监听失败:" << errno << endl;

        exit(0);

    }

    cout << "服务已经开启,正在8080端口监听..." << endl;

    int addr_size = 666; //不能为0

    while (true) {

        /*

          int fd

          sockaddr* addr

          socklen_t len

          成功返回一个新的fd,代表一个与客户端的连接

          失败返回-1

        */

        int client = accept(server, (sockaddr*)& addr, &addr_size);

        if (client == -1) {

            cout << "接收客户异常:" << errno << endl;

            break;

        }

        /*这是c++ 11的新特性: 线程 + 匿名函数*/

        thread t([](sockaddr_in addr, int client) {

            cout << (addr.sin_addr.S_un.S_addr) << ":" << addr.sin_port << endl;

            /*

              int fd

              char* buf,

              size_t len,

              int flag : 一般设为0

              成功,返回接收的字节数,可能部分成功

              对方已关闭,返回0

              失败,返回-1

             */

            char buf[100];

            int reRet = recv(client, buf, sizeof(buf), 0);

            if (reRet == -1) {

                cout << "接收失败:" << errno << endl;

            }

            cout << "收到:" << buf << endl;

            strcpy(buf, "你好客户端");

            /*

              int fd

              const char* buf

              int len

              int flag : 一般设为0

              成功返回发送的字节数,可能部分成功

              失败返回-1

            */

            int seRet = send(client, buf, sizeof(buf), 0);

            if (seRet == -1) {

                cout << "发送失败:" << errno << endl;

            }

        }, addr, client);

        t.detach();

    }

    cout << "服务退出" << errno << endl;

}

客户端:

#include<iostream>
#include<WINSOCK2.H>
#include<STDIO.H>
#include<cstring>
#include <Ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
#define _WINSOCK_DEPRECATED_NO_WARNINGS 1
using namespace std;
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)
{
printf("invalid socket!");
return 0;
}

        sockaddr_in serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(8888);
inet_pton(AF_INET, "127.0.0.1", &serAddr.sin_addr.S_un.S_addr);
if (connect(sclient, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
{  //连接失败 
printf("connect error !");
closesocket(sclient);
return 0;
}

        char data[1024];
cin >> data;
const char * sendData;
sendData = data;   //string转const char* 
//char * sendData = "你好,TCP服务端,我是客户端\n";
send(sclient, sendData, strlen(sendData), 0);
//send()用来将数据由指定的socket传给对方主机
//int send(int s, const void * msg, int len, unsigned int flags)
//s为已建立好连接的socket,msg指向数据内容,len则为数据长度,参数flags一般设0
//成功则返回实际传送出去的字符数,失败返回-1,错误原因存于error 

        char recData[255];
int ret = recv(sclient, recData, 255, 0);
if (ret > 0) {
recData[ret] = 0x00;
printf(recData);
}
closesocket(sclient);
}


WSACleanup();
return 0;

}