【Socket编程】使用C++实现Server端和Client端

来源:互联网 发布:java两个字符串compare 编辑:程序博客网 时间:2024/05/21 22:58

我是在Visual Stdio 2013上建立了两个工程,分别编译运行下面的两个main文件,然后进行测试的

服务端:Server.cpp

#include <WINSOCK2.H>#include <iostream>using std::cout;using std::cin;using std::endl;#include <string>using std::string;#pragma comment(lib,"ws2_32.lib")void main(){    //创建套接字    WORD myVersionRequest;    WSADATA wsaData;                    //包含系统所支持的WinStock版本信息    myVersionRequest = MAKEWORD(1, 1);  //初始化版本1.1    int err;    err = WSAStartup(myVersionRequest, &wsaData);    if (!err){        printf("已打开套接字\n");    }    else{        //进一步绑定套接字        printf("套接字未打开!");        return;    }    SOCKET serSocket = socket(AF_INET, SOCK_STREAM, 0);//创建了可识别套接字    //需要绑定的参数    SOCKADDR_IN addr;    addr.sin_family = AF_INET;    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//ip地址    addr.sin_port = htons(3000);//绑定端口    //将套接字绑定到指定的网络地址    bind(serSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));//绑定完成    listen(serSocket, 10);                              //第二个参数代表能够接收的最多的连接数    SOCKADDR_IN clientsocket;    int len = sizeof(SOCKADDR);    SOCKET serConn;    //等待客户端的连接    serConn = accept(serSocket, (SOCKADDR*)&clientsocket, &len);    cout << "客户端" << inet_ntoa(clientsocket.sin_addr) << "已连接" << endl;             //客户端已连接    while (1) {        char sendBuf[100];        sprintf(sendBuf, "server : welcome %s to server.", inet_ntoa(clientsocket.sin_addr));        //在对应的IP处并且将这行字打印到那里        send(serConn, sendBuf, strlen(sendBuf) + 1, 0);        char receiveBuf[100];        //接收客户端传来的信息        recv(serConn, receiveBuf, strlen(receiveBuf) + 1, 0);        char* quit = "quit";        //如果客户端传来了quit信号,则服务端关闭,客户端也关闭        if (!strcmp(receiveBuf, quit)) {            break;        }        printf("%s\n", receiveBuf);    }    closesocket(serConn);   //关闭    WSACleanup();           //释放资源的操作}

客户端:Client.cpp

#include <WINSOCK2.H>#include <iostream>using std::cout;using std::cin;using std::endl;#include <string>using std::string;#include <conio.h>#pragma comment(lib,"ws2_32.lib")void main(){    int err;    WORD versionRequired;    WSADATA wsaData;                            //包含系统所支持的WinStock版本信息    versionRequired = MAKEWORD(1, 1);           //初始化版本1.1    //注册WinStock,返回状态    err = WSAStartup(versionRequired, &wsaData);//协议库的版本信息    if (!err)                                   //返回结果为0表示初始化失败    {        cout << LPSTR("客户端套接字已经打开!\n");    }    else    {        //调用WSAGetLastError()查看错误信息        cout << ("客户端套接字打开失败:") << WSAGetLastError() << endl;        return;//结束    }    /*    创建套接字:    流式套接字:   SOCK_STREAM , IPPROTO_TCP    数据报套接字: SOCK_DGRAM  , IPPROTO_UDP    */    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //创建流式套接字    SOCKADDR_IN clientsock_in;                                          //专门针对Internet 通信域的Winsock地址结构    clientsock_in.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");        //通过inet_addr结构指定套接字的主机IP地址     clientsock_in.sin_family = AF_INET;                                 //指定协议家族:AF_INET    clientsock_in.sin_port = htons(3000);                               //指定将要分配给套接字的传输层端口号:6000    int fail = connect(clientSocket, (SOCKADDR*)&clientsock_in, sizeof(SOCKADDR));//开始连接    if (fail){        cout << "与服务端连接失败!程序将退出..." << endl;        _getch();        return;    }    string s;    while (cin >> s){        char receiveBuf[100];        //接收数据        recv(clientSocket, receiveBuf, 101, 0);        cout << receiveBuf <<endl;        //发送数据        send(clientSocket, s.c_str(), s.length() + 1, 0);        if (s == "quit"){            break;        }    }    closesocket(clientSocket);    //关闭套接字    if (WSACleanup() == SOCKET_ERROR){        cout << "套接字关闭失败:" << WSAGetLastError() << endl;    }    else{        cout << "套接字成功关闭." << endl;    }    _getch();    return;}//inet_addr结构:/*Struct in_addr {Union{Struct{ u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;Struct{ u_short s_w1, s_w2; } S_un_w;U_long  S_addr;}}*/

测试

这里写图片描述
客户端输入quit后,客户端和服务端则均可正常退出;否则,只关闭客户端,服务端会陷入无限循环输出最后传送的数据(可叉掉)。

备注:

  • 不能支持中文传送数据(会有乱码);
  • 在客户端输入有空格的数据时,会被当成多次输入数据(因为是使用cin读取的数据)

    5 2