C++Socket通信(客戶端和服務器)


win32控制台版

獲取本機IP:

cmd:       ipconfig/all

我寫的是一個服務器和客戶端點對點的信息傳遞(實現相互的可以適當更改代碼):

服務器發送給客戶端的是一個結構體數據

typedef struct Date {
    float m1;
    float m2;
    float m3;
    float m_roll;
    float m_pitch;
    float m_rotate;
}Datablock;

上服務器代碼(阻塞式的):

#include "stdafx.h"
#include <iostream>   
#include <string>   
#include <winsock2.h>   
#pragma comment(lib,"ws2_32.lib")   
using std::cout;
using std::cin;
using std::string;
using std::endl;
typedef struct Date {
    float m1;
    float m2;
    float m3;
    float m_roll;
    float m_pitch;
    float m_rotate;
}Datablock;
int main()
{
    
    cout << "服務器啟動!....." << endl;
    //初始化winsock   
    WSADATA wsaD;
    WSAStartup(MAKEWORD(1, 1), &wsaD);
    //創建監聽套接字   
    SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    // 綁定主機地址和監聽套接字   
    struct sockaddr_in my_addr;   //主機地址   
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(8088); //指定端口   
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(slisten, (struct sockaddr *)&my_addr, sizeof(my_addr));
    //啟動監聽   
    listen(slisten, 5);    //5是最大連接數
                           //開始接收數據   
    struct sockaddr_in c_addr;  //客戶地址   
    int addr_len = sizeof(c_addr);


    SOCKET sconnect = accept(slisten, (struct sockaddr*)&c_addr, &addr_len); //通過監聽套接字創建連接套接字   
    
    cout << "連接已建立......" << endl;

    char buf[500];
    while (true) {
        Datablock client_send;

        cout << "輸入(start)開始更改,輸入(end)結束服務:" << endl;
        cout << "輸入發送內容:";
        while (cin.getline(buf, 500))
        {

            string rcover = buf;
            if (rcover == "end")break;
            if (rcover == "start") {
                cout << "請以m1-m2-m3-m_roll-m_pitch-m_rotate格式輸入數據:" << endl;
                char transmit[100];
                cin.getline(transmit, 100);
                send(sconnect, transmit, strlen(transmit) + 1, 0);  //字符串還有個結束標志
                memset(transmit, 0, sizeof(transmit));        
                

            }
            
        }
        return 0;
    }

客戶端:(非阻塞式的)

首先要有宏(一般放在.h文件的頭文件區域)

#include "stdafx.h"
#include <iostream>   
#include <string>  
#include<cstring>
#include <winsock2.h>  
#include <WS2tcpip.h> 
#include<vector>
#include<sstream>
#pragma comment(lib,"ws2_32.lib")   
using namespace std;
typedef struct Date {
    float m1;
    float m2;
    float m3;
    float m_roll;
    float m_pitch;
    float m_rotate;
}Datablock;
void splitEx(vector<string>&strs, const string& src, string separate_character)
{


    int separate_characterLen = separate_character.size();//分割字符串的長度,這樣就可以支持如“,,”多字符串的分隔符
    int lastPosition = 0, index = -1;
    while (-1 != (index = src.find(separate_character, lastPosition)))
    {
        strs.push_back(src.substr(lastPosition, index - lastPosition));
        lastPosition = index + separate_characterLen;
    }
    string lastString = src.substr(lastPosition);//截取最后一個分隔符后的內容
    if (!lastString.empty())
        strs.push_back(lastString);//如果最后一個分隔符后還有內容就入隊

}
float str_float(string a) {
    float b;
    stringstream ss;                              //string 轉 int
    ss << a;
    ss >> b;
    return b;
}
int main()
{
    cout << "客戶端啟動" << endl;
    //初始化winsock   
    WSADATA wsaD;
    WSAStartup(MAKEWORD(1, 1), &wsaD);
    //創建客戶端socket   
    SOCKET sclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //連接服務器   
    u_long iMode = 1;//如果設置為0,為阻塞式的
    ioctlsocket(sclient, FIONBIO, &iMode);
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;

    cout << "請輸入局域網IP地址:" << endl;
    string ipaddress;
    cin >> ipaddress;

    cout << ipaddress;

    servaddr.sin_addr.s_addr = inet_addr(ipaddress.c_str()); //指定服務器   
    servaddr.sin_port = htons(8088);             //指定端口   
    cout << endl<<"OK" << endl;

        connect(sclient, (struct sockaddr*)&servaddr, sizeof(servaddr)); //通過套接字連接主機   

    

        char buf[500];
        
        Datablock resu_data;
        while (true) {
            //存儲接收的字符   
            int len = recv(sclient, buf, sizeof(buf), 0);  //通過連接套接字接收數據
            
            if (len > 0)
            {
                vector<string>result;
                cout << "客戶說:" << buf << endl;    
                string test = buf;
                cout << test << endl;
                splitEx(result, test, "-");        
                resu_data.m1 = str_float(result[0]);
                resu_data.m2 = str_float(result[1]);
                resu_data.m3 = str_float(result[2]);
                resu_data.m_roll = str_float(result[3]);
                resu_data.m_pitch = str_float(result[4]);
                resu_data.m_rotate = str_float(result[5]);
                cout << resu_data.m1 << endl;
                cout << resu_data.m2 << endl;
                cout << resu_data.m3 << endl;
                cout << resu_data.m_roll << endl;
                cout << resu_data.m_pitch<< endl;
                cout << resu_data.m_rotate << endl;        
            }        
        }
        
        return 0;
}

這是一個點對點的,先開server,后開客戶端。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM