[JSBSim]基于winsocket2的TCP\UDP使用例子

TCP部分:

参考:http://blog.csdn.net/sbfksmq/article/details/50808863

 

另附:linux下的tcp/udp参考:https://www.cnblogs.com/lyggqm/p/9111010.html

TCP_SEVER:

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

#include "stdafx.h"

//服务器  
#include<iostream>  
#include<WinSock2.h>                    // socket 所需要的头文件  
#pragma comment(lib,"WS2_32.lib")// link socket 库  
#define PORT 9999   
#define BUFLEN 1024  
using namespace std;
int main()
{
    WSADATA wsaData;
    // 1 启动并初始化winsock(WSAStarup)  
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))//成功返回0  
    {
        return FALSE;
    }
    //2 创建套接字(socket)  
    SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sServer)
    {
        WSACleanup();
        return FALSE;
    }
    //3 准备通信地址  
    SOCKADDR_IN addrServer;
    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(PORT);
    addrServer.sin_addr.s_addr = INADDR_ANY;//任意可用地址  
                                            //4 绑定地址与socket(bind)  
    if (SOCKET_ERROR == bind(sServer, (const sockaddr*)&addrServer, sizeof(SOCKADDR_IN)))
    {
        closesocket(sServer);
        WSACleanup();

        return FALSE;
    }
    //5 监听 (listen)  
    if (SOCKET_ERROR == listen(sServer, SOMAXCONN))
    {
        closesocket(sServer);
        WSACleanup();
    }
    // 6 等待客户端连接(accpet)  
    sockaddr_in addrClient;
    int addrClientLen = sizeof(addrClient);
    cout << "服务器启动成功,等待客户端连接中。。。。" << endl;
    SOCKET sClient = accept(sServer, (sockaddr *)&addrClient, &addrClientLen);
    if (INVALID_SOCKET == sClient)
    {
        cout << WSAGetLastError() << endl;
        closesocket(sServer);
        closesocket(sClient);
        WSACleanup();
        return FALSE;
    }
    //7 接收数据(recv)  
    char recvBuf[BUFLEN];
    ZeroMemory(recvBuf, sizeof(recvBuf));
    if (SOCKET_ERROR == recv(sClient, recvBuf, sizeof(recvBuf), 0))
    {
        closesocket(sServer);
        closesocket(sClient);
        WSACleanup();
        return FALSE;
    }
    cout << "客户端(" << inet_ntoa(addrClient.sin_addr) << ":" << addrClient.sin_port << "):" << recvBuf << endl;
    //8 发送数据  
    char sendBuf[BUFLEN] = "你好客户端!";
    if (SOCKET_ERROR == send(sClient, sendBuf, sizeof(sendBuf), 0))
    {
        closesocket(sServer);
        closesocket(sClient);
        WSACleanup();
        return FALSE;
    }
    system("pause");
    system("pause");
    return TRUE;
}
/*
注:1:MAKEWORD把参数组成一个WORD(双字节)类型数据并返回这个WORD类型数值,高位代表(修订本)号,低位字节指定主版本号(其代表)
2:socket(AF_INET,//The Internet Protocol version 4 (IPv4) address family
SOCK_STREAM,//, two-way,This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6).
IPPROTO_TCP//The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_STREAM.
)
*/

 

TCP_CLIENT:

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

#include "stdafx.h"

//客户端  
#include<iostream>  
#include<WinSock2.h>  
#pragma comment(lib,"WS2_32.lib")  
using namespace std;
#define BUFLEN 1024  
#define PORT 9999   
void getIP(char*szHostaddress);
int main()
{

    WSADATA wsaData;
    // 1 启动并初始化winsock(WSAStarup)  
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))//成功返回0  
    {
        return FALSE;
    }
    //2 创建套接字(socket)  
    SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == sHost)
    {
        closesocket(sHost);
        WSACleanup();
        return FALSE;
    }
    //3 准备通信地址  
    char szHostaddress[200];
    getIP(szHostaddress);
    SOCKADDR_IN addrServer;
    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(PORT);
    addrServer.sin_addr.s_addr = inet_addr(szHostaddress);
    //4 连接服务器(connect)  
    if (SOCKET_ERROR == connect(sHost, (const sockaddr*)&addrServer, sizeof(addrServer)))
    {
        closesocket(sHost);
        WSACleanup();
        return FALSE;
    }
    //5 发送数据 (send)  
    char sendBuf[BUFLEN] = "你好服务器!";
    if (SOCKET_ERROR == send(sHost, sendBuf, sizeof(sendBuf), 0))
    {
        closesocket(sHost);
        WSACleanup();
        return FALSE;
    }
    cout << "客户端发送消息成功!" << endl;
    //7 接收数据(recv)  
    char recvBuf[BUFLEN];
    ZeroMemory(recvBuf, sizeof(recvBuf));
    if (SOCKET_ERROR == recv(sHost, recvBuf, sizeof(recvBuf), 0))
    {
        closesocket(sHost);
        WSACleanup();
        return FALSE;
    }
    cout << "服务器发来的消息:" << recvBuf << endl;
    system("pause");
}
void getIP(char*szHostaddress) {
    char szHostname[100];
    if (gethostname(szHostname, sizeof(szHostname)) != SOCKET_ERROR)//先得到主机名  
    {
        HOSTENT *pHostEnt = gethostbyname(szHostname);//通过名字拿到地址  
        if (pHostEnt != NULL)
        {
            sprintf(szHostaddress, "%d.%d.%d.%d",
                (pHostEnt->h_addr_list[0][0] & 0x00ff),
                (pHostEnt->h_addr_list[0][1] & 0x00ff),
                (pHostEnt->h_addr_list[0][2] & 0x00ff),
                (pHostEnt->h_addr_list[0][3] & 0x00ff));
        }
    }
    else
        return;
}

 

UDP部分:

参考:http://blog.csdn.net/sbfksmq/article/details/51046439

UDP_SERVER:

// 服务端  
// UDP.cpp : 定义控制台应用程序的入口点。  
//1 为UDP通信,单例模式  
//2 一些socket函数不兼容 预处理器定义里添加如下的宏  
//_WINSOCK_DEPRECATED_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_DEPRECATE;  
//3 UDP为非面向连接方式不需要listen 与accept  
#include"stdafx.h"  
#include"afxwin.h"  
#include"WinSock2.h"  
#include<iostream>  
#include <ws2tcpip.h>  
#pragma comment(lib,"WS2_32.lib")  
using namespace std;  
//日志 可以不看  
bool WriteErrorLogFile(CString csData)// errorlog  
{  
    char buff[256];  
    CString ErrorLog;  
    GetModuleFileName(NULL, (LPWSTR)buff, sizeof(buff));  
    cout << buff << endl;  
    ErrorLog = CString(buff);  
    ErrorLog += ErrorLog.Left(ErrorLog.ReverseFind('\\')) + "\\ErrorLog";  
  
    CString stemp;  
    CString sPathName;  
    SYSTEMTIME sys_time;  
    GetLocalTime(&sys_time);  
  
    sPathName = ErrorLog;  
  
    stemp.Format(L"%d%d%d", sys_time.wYear, sys_time.wMonth, sys_time.wDay);  
    sPathName += "\\" + stemp;  
  
    CreateDirectory(sPathName, NULL);  
  
    CStdioFile f;  
    if (!f.Open(sPathName, CStdioFile::modeCreate | CStdioFile::modeNoTruncate | CStdioFile::modeWrite | CStdioFile::typeText))  
    {  
        return false;  
    }  
    f.SeekToEnd();  
    stemp.Format(L"%02d:%02d:%02d:%s\n", sys_time.wHour, sys_time.wMinute, sys_time.wSecond, csData);  
    f.WriteString(stemp);  
    f.Flush();  
    f.Close();  
    return true;  
}  
class UDPSERVER  
{//私有  
    UDPSERVER(char *ip, char*port) :m_IP(ip), m_Port(port)  
    {  
        m_srvSocket = INVALID_SOCKET;  
        //init  
    //  Init();   
    }  
    UDPSERVER(UDPSERVER const &that)  
    {  
  
    }  
public:  
    static UDPSERVER *Instance(char*ip,char*port)  
    {  
        if (!_instance)  
        {  
            _instance = new UDPSERVER(ip, port);  
        }  
        return _instance;  
    }  
    static bool Init()  
    {  
        WSADATA wsaData;  
        try {  
            if (WSAStartup(0X202, &wsaData))//If successful, the WSAStartup function returns zero  
            {  
                int err = WSAGetLastError();  
  
                WSACleanup();  
                return true;  
            }  
        }  
        catch (...)  
        {  
            cout << "WSAStartup error code:" << WSAGetLastError() << endl;  
            return false;  
        }  
        return true;  
    }  
    static bool GetLocalIp(char *szIP)// 获取IP  
    {  
        char szHostName[128];  
        ZeroMemory(szHostName, sizeof(szHostName));  
        if (gethostname(szHostName, sizeof(szHostName))== 0)//gethostname 函数要在WSAStartup后进行调用。。。  
        {  
        //  cout << "szHostName = " <<szHostName<< endl;   
            HOSTENT*pHostEnt = gethostbyname(szHostName);  
            if (pHostEnt)  
            {  
                sprintf(szIP, "%d.%d.%d.%d", (pHostEnt->h_addr_list[0][0] & 0xff),  
                    (pHostEnt->h_addr_list[0][1] & 0xff),  
                    (pHostEnt->h_addr_list[0][2] & 0xff),  
                    (pHostEnt->h_addr_list[0][3] & 0xff));  
                //cout<<szIP<<endl;  
                return true;  
            }  
        }  
        else   
        {  
            cout << "gethostname error code:" << WSAGetLastError()<<endl;  
            return false;  
        }  
        return true;  
    }  
    bool StartServer()  
    {  
  
        // create socket  
        m_srvSocket = socket(AF_INET, SOCK_DGRAM, 0);  
        if (INVALID_SOCKET == m_srvSocket)  
        {  
            WSACleanup();  
            char errBuf[16];  
            WriteErrorLogFile(CString(itoa(WSAGetLastError(), errBuf, sizeof(errBuf))));  
            return false;  
        }  
        // address  
          
        pAddrServer.sin_family = AF_INET;  
        pAddrServer.sin_port = htons(atoi(m_Port));  
        pAddrServer.sin_addr.s_addr = inet_addr(m_IP);//or INADDR_ANY:接收任意IP发来的数据或指定一个IP发送数据   
        //bind  
        if (bind(m_srvSocket, (const sockaddr*)&pAddrServer, sizeof(SOCKADDR_IN)))  
        {  
            WSACleanup();  
            closesocket(m_srvSocket);  
            char errBuf[16];  
            WriteErrorLogFile(CString(itoa(WSAGetLastError(), errBuf, sizeof(errBuf))));  
            return false;  
        }  
        //jUDP no need to listen or accept  
        return true;   
    }  
        void RcvData(char*buff = NULL)  
        {  
            int nSrvAddrLen = sizeof(SOCKADDR);  
            char bufMessage[1024];  
            ZeroMemory(bufMessage, sizeof(bufMessage));  
            int nRetRcv = recvfrom(m_srvSocket, bufMessage, sizeof(bufMessage), 0, (sockaddr*)&pAddrServer, (int *)  
                &nSrvAddrLen);  
            /*recv,send,(TCP)从一个已连接的socket接收或发送数据  
            sendto,recvfrom(UDP/TCP):从一个已连接或未连接的socket接收或发送数据 
            当你对于数据报socket调用了connect()函数时,你也可以利用send()和recv()进行数据传输, 
            但该socket仍然是数据报socket,并且利用传输层的UDP服务。但在发送或接收数据报时,内核会自动为之加上目地和源地址信息。*/  
            //不管是recv还是recvfrom,都有两种模式,阻塞和非阻塞,可以通过ioctl函数来设置   
              
            if (0 == nRetRcv)  
            {  
                WSACleanup();  
                closesocket(m_srvSocket);  
                char errBuf[16];  
                WriteErrorLogFile(CString(itoa(WSAGetLastError(), errBuf, sizeof(errBuf))));  
            }  
            cout << "the client:"<<inet_ntoa(pAddrServer.sin_addr)<<" say:" << bufMessage << endl;  
        }  
        void SentData(char*buff=NULL)  
        {   
            // sendto  
            SOCKADDR_IN clientAddr;  
            clientAddr.sin_family = AF_INET;  
            clientAddr.sin_port = htons((short)6666);//发送到的端口  
            clientAddr.sin_addr.s_addr = inet_addr(m_IP);  
  
            int nRetSent = sendto(m_srvSocket,"hello client",sizeof("hello client"),0, (SOCKADDR*)&clientAddr, sizeof(clientAddr));  
            if (0 == nRetSent)  
            {  
                WSACleanup();  
                closesocket(m_srvSocket);  
                char errBuf[16];  
                WriteErrorLogFile(CString(itoa(WSAGetLastError(), errBuf, sizeof(errBuf))));  
            }  
        }  
private:  
    char *m_IP;  
    char *m_Port;  
    SOCKET m_srvSocket;  
    SOCKADDR_IN  pAddrServer ;  
    static UDPSERVER* _instance;  
};  
UDPSERVER*UDPSERVER::_instance = NULL;  
int main(int argc,char*argv[])  
{  
    char szIP[16] = {};  
    UDPSERVER::Init();  
    if (false != UDPSERVER::GetLocalIp(szIP))  
    {  
        UDPSERVER* pUdpServer = UDPSERVER::Instance(szIP, "8888");  
        if (pUdpServer->StartServer())  
        {  
            while (1)  
            {  
                pUdpServer->RcvData();  
                pUdpServer->SentData();            
            }  
        }  
        else  
        {  
            delete pUdpServer;  
            pUdpServer = NULL;  
        }  
    }  
    system("pause");  
    return 0;  
}  

UDP_CLIENT:

//客户端  
#include "stdafx.h"  
#include <winsock2.h>  
#include <ws2tcpip.h>  
#include <stdio.h>  
#include<iostream>  
#pragma comment (lib, "Ws2_32.lib")  
using namespace std;  
int  main(int argc, char **argv)  
{  
    //1 初始化  
    WSADATA wsaData;  
    SOCKET  sServer;  
    WSAStartup(0x202, &wsaData);  
    //2 创建绑定socket  
    sServer = socket(AF_INET, SOCK_DGRAM, 0);  
    SOCKADDR_IN srvAddr;  
    srvAddr.sin_family = AF_INET;  
    srvAddr.sin_port = htons(6666);  
    srvAddr.sin_addr.s_addr = inet_addr("172.168.28.201");  
    bind(sServer, (const sockaddr*)&srvAddr, sizeof(srvAddr));  
   //3 准备数据传输目的地的地址与数据  
    int nSrvAddrLen = sizeof(srvAddr);  
    char szSendBuff[1024];  
    ZeroMemory(szSendBuff, sizeof(szSendBuff));  
    memcpy(szSendBuff, "hello server", sizeof("hello server"));  
    SOCKADDR_IN cltAddr;  
    cltAddr.sin_family = AF_INET;  
    cltAddr.sin_port = htons(8888);// 发送到哪个端口            htons主机字节顺序转变成网络字节顺序  
    cltAddr.sin_addr.s_addr = inet_addr("172.168.28.201");//inet_addr 字符串转换为32位二进制网络字节序的IPV4地址  
    int nCltAddrLen = sizeof(cltAddr);  
    // 发送   
    sendto(sServer, szSendBuff, sizeof(szSendBuff), 0, (const sockaddr*)&cltAddr, nCltAddrLen);  
    // 接收  
    memset(szSendBuff, 0, sizeof(szSendBuff));  
    recvfrom(sServer, szSendBuff, sizeof(szSendBuff), 0, ( sockaddr*)&srvAddr, &nSrvAddrLen);  
  
    /*inet_pton inetntop 可以在将IP地址在“点分十进制”和“网络二进制结构”之间转换。而且,这2个函数能够处理ipv4和ipv6。算是比较新的函数*/  
    struct protoent *pe  = getprotobyname("udp");  
    //getpeername(sServer, (sockaddr*)&srvAddr, &nSrvAddrLen);  
    cout << "the client receive the message: " << endl;  
    cout << "/* the server ip:" << inet_ntoa(srvAddr.sin_addr) << endl;//inet_ntoa 将网络地址转换成“.”点隔的字符串格式  
    cout << "  the server  port is " <<ntohs(srvAddr.sin_port) << endl;//htons  
    cout << "  the server protocol:" << pe->p_name << endl;  
    cout << "  the server protocal num is " << pe->p_proto << endl;  
    cout << "  the server message is : "<< szSendBuff << " */ " << endl;  
    system("pause");  
    return 0;  
}  

 

SELECT部分:

参考:http://blog.csdn.net/sbfksmq/article/details/51051585

SELECT_SERVER:

// WinSelectModel.cpp : 定义控制台应用程序的入口点。  
//  
//server side ,select model  
/* 
Syntax:  
int select( 
_In_    int                  nfds,//Ignored. The nfds parameter is included only for compatibility with Berkeley sockets. 
_Inout_ fd_set               *readfds,//An optional pointer to a set of sockets to be checked for readability. 
_Inout_ fd_set               *writefds,//An optional pointer to a set of sockets to be checked for writability. 
_Inout_ fd_set               *exceptfds,//An optional pointer to a set of sockets to be checked for errors. 
_In_    const struct timeval *timeout//The maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations. 
) 
功能:简单的讲就是一个socket“复用器”(不必为第个客户建立新线程,但需要不断轮询fd_set检测,fd_set的大小固定64),它能够检测报告一个或多个socket状态 ,但不如WSAASyncSelct()那么细致,第次调用,select ()把一组socket作为输入参数,而且它是阻塞的(可设置),也就是说该函数能使你同时检测多个socket的状态,它需要通过返回值来带回执行结果 
Return value:成功返回当前状态与设定状态相匹配的socket的总数,超时返回0(timeout参数),失败返回SOCKET_ERROR  
remarks:它与BSD兼容 ,也可以使用WSAAsyncSelect() ,timeout非零则阻塞,零则不阻塞(但不要传NULL为无限阻塞) 
应用:网络连接数不大的程序  
与select配合使用的宏 
FD_ZERO(*set) :对fd_set初始化 
FD_SET(s, *set):添加指定s套接字至集合 
FD_CLR(s, *set):删除指定s套接字至集合 
FD_ISSET(s, *set):检查指定s套接字是否集合 
FD_SETSIZE: 64  
*/  
#include "stdafx.h"  
#include<iostream>  
#include<WinSock2.h>                    // socket 所需要的头文件  
#pragma comment(lib,"WS2_32.lib")// link socket 库  
#define PORT 6666   
#define BUFLEN 1024  
using namespace std;  
fd_set g_fdClientSocket;  
//fd_set   
DWORD WINAPI ThreadProc(LPVOID lpParameter);  
int main()  
{  
  
    DWORD dwThreadID;  
    sockaddr_in addrClient;  
    int addrClientLen = sizeof(addrClient);  
    SOCKET sServer = INVALID_SOCKET;  
    SOCKET sClient;  
    int nClientCount = 0;  
    // 1 启动并初始化winsock(WSAStarup)  
    WSADATA wsaData;  
    if (WSAStartup(0x202, &wsaData))//成功返回0  
    {  
        return FALSE;  
    }  
    //2 创建套接字(socket)  
     sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
    if (INVALID_SOCKET == sServer)  
    {  
        WSACleanup();  
        return FALSE;  
    }  
    //3 准备通信地址  
    SOCKADDR_IN addrServer;  
    addrServer.sin_family = AF_INET;  
    addrServer.sin_port = htons(PORT);//服务器用于监听的端口号,客户端需要知道这个端口进行连接  
    addrServer.sin_addr.s_addr =  INADDR_ANY;  
    //4 绑定地址与socket(bind)  
    if (SOCKET_ERROR == bind(sServer, (const sockaddr*)&addrServer, sizeof(SOCKADDR_IN)))  
    {  
        closesocket(sServer);  
        WSACleanup();  
        return FALSE;  
    }  
    //5 监听 (listen)  
    if (SOCKET_ERROR == listen(sServer, SOMAXCONN))  
    {  
        closesocket(sServer);  
        WSACleanup();  
    }  
    //6 线程利用select()处理可读的客户端  
    CreateThread(NULL, 0, ThreadProc, NULL, 0, &dwThreadID);  
    // 7 等待多个客户端连接(accpet)  
    while (nClientCount<FD_SETSIZE)   
    {  
         sClient= accept(sServer, (sockaddr *)&addrClient, &addrClientLen);  
        if (INVALID_SOCKET == sClient)  
        {  
            cout << WSAGetLastError() << endl;  
            //或根据错误码进行其他操作  
            closesocket(sServer);  
            closesocket(sClient);  
            WSACleanup();  
            return FALSE;  
        }  
        printf("Accepted client:%s:%d\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port));  
        FD_SET(sClient,& g_fdClientSocket);  
        nClientCount++;  
    }  
    system("pause");  
    return TRUE;  
}  
// 只处理是可读状态的socket  
DWORD WINAPI ThreadProc(LPVOID lpParameter)  
{  
    fd_set fdRead;  
    fd_set fdWrite;  
    FD_ZERO(&fdRead);  
    FD_ZERO(&fdWrite);  
  
    int nRet = 0;  
  
    char recvBuffer[1024] = {};  
  
    struct timeval stTimeOut = { 1,0 };  
  
    while (true)  
    {  
        fdRead = g_fdClientSocket;  
        fdWrite = g_fdClientSocket;  
        nRet = select(0, &fdRead, &fdWrite, NULL, &stTimeOut);  
        if (SOCKET_ERROR != nRet)  
        {  
            for (int i = 0; i < g_fdClientSocket.fd_count; i++)  
            {  
                if (FD_ISSET(g_fdClientSocket.fd_array[i], &fdRead))  
                {  
                    memset(recvBuffer, 0, sizeof(recvBuffer));  
                    SOCKADDR_IN stAddrTemp;  
                    int nTempLen = sizeof(stAddrTemp);  
                    nRet = recvfrom(g_fdClientSocket.fd_array[i], recvBuffer, sizeof(recvBuffer), 0, (sockaddr*)&stAddrTemp, &nTempLen);  
                    if (SOCKET_ERROR == nRet)  
                    {  
                        closesocket(g_fdClientSocket.fd_array[i]);  
                        FD_CLR(g_fdClientSocket.fd_array[i], &g_fdClientSocket);  
                    }  
                    else  
                    {  
                        cout << "the client(" << inet_ntoa(stAddrTemp.sin_addr) << ":" << ntohs(stAddrTemp.sin_port) << ") :" << recvBuffer << "(message size is " << nTempLen << ")" << endl;  
                    }  
                }  
                if (FD_ISSET(g_fdClientSocket.fd_array[i], &fdWrite))  
                {  
                    nRet = send(g_fdClientSocket.fd_array[i], "hello Client", sizeof("hello Client"), 0);  
                    if (SOCKET_ERROR == nRet)  
                    {  
                        int nErrorNo = WSAGetLastError();  
                        cout << "send error code is " << nErrorNo << endl;//10038  socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.  
                        closesocket(g_fdClientSocket.fd_array[i]);  
                        FD_CLR(g_fdClientSocket.fd_array[i], &g_fdClientSocket);  
                    }  
                    else  
                    {  
                        continue;  
                    }  
                }  
            }  
        }  
    }  
}  

 

SELECT_CLIENT:

// WinSelectClient.cpp : 定义控制台应用程序的入口点。  
//  
  
#include "stdafx.h"  
#include<WinSock2.h>  
//客户端   
#include<iostream>  
#pragma comment(lib,"WS2_32.lib")  
using namespace std;  
#define BUFLEN 1024  
#define PORT 6666  
void getIP(char*szHostaddress);  
void SendProc();  
SOCKET sHost;  
int main()  
{  
    WSADATA wsaData;  
    // 1 启动并初始化winsock(WSAStarup)  
    if (WSAStartup(MAKEWORD(2, 2), &wsaData))//成功返回0  
    {  
        return FALSE;  
    }  
    //2 创建套接字(socket)  
    sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
    if (INVALID_SOCKET == sHost)  
    {  
        closesocket(sHost);  
        WSACleanup();  
        return FALSE;  
    }  
    //3 准备通信地址  
    char szHostaddress[200];  
    getIP(szHostaddress);  
    SOCKADDR_IN addrServer;  
    addrServer.sin_family = AF_INET;  
    addrServer.sin_port = htons(PORT);  
    addrServer.sin_addr.s_addr = inet_addr(szHostaddress);  
    //4 连接服务器(connect)  
    if (SOCKET_ERROR == connect(sHost, (const sockaddr*)&addrServer, sizeof(addrServer)))//连接到指定的地址  
    {  
        closesocket(sHost);  
        WSACleanup();  
        return FALSE;  
    }  
    //5 发送数据 (send)  
    char sendBuf[BUFLEN] = "你好服务器!";  
    if (SOCKET_ERROR == send(sHost, sendBuf, sizeof(sendBuf), 0))  
    {  
        closesocket(sHost);  
        WSACleanup();  
        return FALSE;  
    }  
    cout << "客户端发送消息成功!" << endl;  
    //7 接收数据(recv)  
    char recvBuf[BUFLEN];  
    ZeroMemory(recvBuf, sizeof(recvBuf));  
    if (SOCKET_ERROR == recv(sHost, recvBuf, sizeof(recvBuf), 0))  
    {  
        closesocket(sHost);  
        WSACleanup();  
        return FALSE;  
    }  
    cout << "服务器发来的消息:" << recvBuf << endl;  
    while (true)  
    {  
        SendProc();  
        Sleep(1000);  
    }  
    system("pause");  
}  
void SendProc(  
    )  
{  
    char sendBuf[BUFLEN] = "你好服务器!";  
    if (SOCKET_ERROR == send(sHost, sendBuf, sizeof(sendBuf), 0))  
    {  
        closesocket(sHost);  
        WSACleanup();  
        return ;  
    }  
    cout << "客户端发送消息成功!" << endl;  
}  
  
void getIP(char*szHostaddress) {  
    char szHostname[100];  
    if (gethostname(szHostname, sizeof(szHostname)) != SOCKET_ERROR)//先得到主机名  
    {  
        HOSTENT *pHostEnt = gethostbyname(szHostname);//通过名字拿到地址  
        if (pHostEnt != NULL)  
        {  
            sprintf(szHostaddress, "%d.%d.%d.%d",  
                (pHostEnt->h_addr_list[0][0] & 0x00ff),  
                (pHostEnt->h_addr_list[0][1] & 0x00ff),  
                (pHostEnt->h_addr_list[0][2] & 0x00ff),  
                (pHostEnt->h_addr_list[0][3] & 0x00ff));  
        }  
    }  
    else  
        return;  
}  

 

posted @ 2017-03-16 10:08  南水之源  阅读(4069)  评论(0编辑  收藏  举报