C++基础--Socket C/S UDP通信

原来,UDP通信,比我想象中简单的多!

// WindowsSocketServer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <Windows.h>
#include <Winsock2.h>
#include <fstream>
#pragma comment(lib,"Ws2_32.lib")

using namespace std;
#define PORT 8080
#define IP_ADDRESS "172.16.20.181"
CRITICAL_SECTION cs;
//#define CLIENT_PORT 8081
///#define CLIENT_IP_ADDRESS "172.16.20.181"

//接收每个客户端连接的处理函数
DWORD WINAPI ClientThread(LPVOID lpParameter);

//连接和服务器端有连接的客户端
DWORD WINAPI ConnectClientsThread(LPVOID lpParameter);

  int main(int argc, char* argv[])
  {
    //版本协商 
    WORD wVersionRequested; 
    WSADATA wsaData; 
    int err; 
    wVersionRequested = MAKEWORD( 1, 1 ); 
    err = WSAStartup( wVersionRequested, &wsaData ); 
    if ( err != 0 ) { 
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        return 0; 
    } 
    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
    if ( LOBYTE( wsaData.wVersion ) != 1 || 
        HIBYTE( wsaData.wVersion ) != 1) { 
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        WSACleanup( ); 
         return 0;  
    } 
    /* The WinSock DLL is acceptable. Proceed. */
    //创建数据报套接字  
    SOCKET svr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 
    //创建本地地址信息 
    SOCKADDR_IN addr; 
    addr.sin_family = AF_INET; 
    addr.sin_port = htons(6000); 
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); 
    int len = sizeof(sockaddr); 
    int bindflag = bind(svr,(sockaddr*)&addr,len); 
    if( bindflag ==SOCKET_ERROR )
    {
        printf("服务器绑定失败!\n");
        system("pause");
        return 0;
    }
    else
    {
        printf("服务器端绑定完成。\n");
    }
    //创建客户端地址对象 
    SOCKADDR_IN addrClient; 
    char recvBuf[128]; 
    char sendBuf[128]; 
    char tempBuf[256];
    while(true) 
    { 
        //接收数据 
        recvfrom(svr,recvBuf,128,0,(sockaddr*)&addrClient,&len); 
        char* ipClient = inet_ntoa(addrClient.sin_addr); 
        sprintf(tempBuf,"接收来自客户端 %s 的数据: %s\n",ipClient,recvBuf); 
        printf("%s",tempBuf); 
        gets_s(sendBuf);
        //发送数据 
        sendto(svr,sendBuf,strlen(sendBuf)+1,0,(sockaddr*)&addrClient,len); 
    } 
    closesocket(svr); 
    WSACleanup();  
    return 0;
  }
// WindowsSocketClient.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <Winsock2.h>
#include <Windows.h>
#include <fstream>
#include <map>
#include <string>
#include <sstream>

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

using namespace std;

#define PORT 8080
#define IP_ADDRESS "172.16.20.181"

#define LISTEN_PORT 8081
#define LISTEN_IP_ADDRESS "172.16.20.181"
//发送消息结构体
struct SendMsgStruct
{
    SOCKET clientSocket;
    string msg;
    struct sockaddr_in ServerAddr;
};

//接收消息结构体
struct RecvMsgStruct
{
    SOCKET  clientSocket;
    struct sockaddr_in ServerAddr;
};

//发送消息子线程
DWORD WINAPI SendThread(LPVOID lpParameter);

//接收消息子线程
DWORD WINAPI RecvThread(LPVOID lpParameter);

//去除字符串首尾空格
void trim(string &str);

//监听服务器的连接
DWORD WINAPI ListenServerThread(LPVOID lpParameter);

int _tmain(int argc, _TCHAR* argv[])
{
    //版本协商 
    WORD wVersionRequested; 
    WSADATA wsaData; 
    int err; 
    wVersionRequested = MAKEWORD( 1, 1 );
    err = WSAStartup( wVersionRequested, &wsaData ); 
    if ( err != 0 ) { 
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        return 0; 
    } 
    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
    if ( LOBYTE( wsaData.wVersion ) != 1 || 
        HIBYTE( wsaData.wVersion ) != 1 ) { 
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        WSACleanup( ); 
        return 0;  
    } 

    /* The WinSock DLL is acceptable. Proceed. */
    //创建服务器套接字 
    SOCKET Svr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 
    //创建地址 
    SOCKADDR_IN addrSvr; 
    addrSvr.sin_family = AF_INET; 
    addrSvr.sin_port = htons(6000); 
    addrSvr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 
    char recvBuf[128]; 
    char sendBuf[128]; 
    int len = sizeof(sockaddr); 
    while(true) 
    { 
        printf("输入数据,传输给服务端"); 
        gets(sendBuf); 
        //发送数据 
        sendto(Svr,sendBuf,strlen(sendBuf)+1,0,(sockaddr*)&addrSvr,len); 
        //接收数据 
        recvfrom(Svr,recvBuf,128,0,(sockaddr*)&addrSvr,&len); 
        char* ipSvr = inet_ntoa(addrSvr.sin_addr); 
        printf("来自 %s 的消息: %s\n",ipSvr,recvBuf); 
    } 
    closesocket(Svr); 
    WSACleanup();  
    return 0;
}

//接收消息子线程
DWORD WINAPI RecvThread(LPVOID lpParameter)
{

    RecvMsgStruct *recvStruct=(RecvMsgStruct *)lpParameter;
    SOCKET clientSocket = recvStruct->clientSocket;
    struct sockaddr_in ServerAddr = recvStruct->ServerAddr;
    char recvBuf[500]={"0"}; 
     int byteRecv = recv(clientSocket, recvBuf, 500, 0);
     int connectState;
     while( byteRecv == 0 )
     {
         //连接断开,重连
        cout<<"byteRecv == 0"<<endl;
        shutdown(clientSocket,2);
        //closesocket(ClientSocket);
        clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        connectState = connect(clientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr));

        if( connectState == SOCKET_ERROR )
        {
            cout<<"建立连接发生错误,错误代码:"<<GetLastError()<<endl;
        }
        else
        {
            cout<<"-----------------------------------------------In"<<endl;
        }
        Sleep(5000);
     }
    cout<<recvBuf<<endl;
    while( true ){}
    return 0;
}

//移除字符串首尾空格
void trim(string &str)
{
      str.erase(str.find_last_not_of(' ')+1,string::npos);
      str.erase(0,str.find_first_not_of(' '));
}
posted @ 2012-07-01 16:42  Kingdom_0  阅读(529)  评论(0编辑  收藏  举报