简单网络编程--TCP SERVER 端

来源:互联网 发布:网络翻墙是什么意思 编辑:程序博客网 时间:2024/06/01 07:34

 

一个服务器,接受客户连接,返回客户IP地址,并关闭连接。

一个服务器程序的基本步骤:
1. winsock library 的初始化
2. 创建socket
3. 服务器地址
4. bind->listen
5. 等待客户连接 accept
6. 处理客户接入
7. 关闭 socket
8. 释放资源:winsock library

// SimpleTcpServer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"ws2_32")
#include "SimpleTcpServer.h"

#include <conio.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object
//z 2011-05-22 21:23:03@is2120

CWinApp theApp;

using namespace std;

UINT  ServerThread(LPVOID pParam);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
  int nRetCode = 0;

  // initialize MFC and print and error on failure
  if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  {
    // TODO: change error code to suit your needs
    cerr << _T("Fatal Error: MFC initialization failed") << endl;
    nRetCode = 1;
  }
  else
  {
    // TODO: code your application's behavior here.
    /*
    CString strHello;
    strHello.LoadString(IDS_HELLO);
    cout << (LPCTSTR)strHello << endl;
    */
    int nRetCode = 0
    
    cout << "Press ESCAPE to terminate program/r/n";
    AfxBeginThread(ServerThread,0);
    while(_getch()!=27);
    
    return nRetCode;
  }

  return nRetCode;
}

UINT  ServerThread(LPVOID pParam)

    cout << "Starting up TCP server/r/n";

    //A SOCKET is simply a typedef for an unsigned int.

    //In Unix, socket handles were just about same as file 

    //handles which were again unsigned ints.

    //Since this cannot be entirely true under Windows

    //a new data type called SOCKET was defined.

    SOCKET server;

    //WSADATA is a struct that is filled up by the call 

    //to WSAStartup

    WSADATA wsaData;

    //The sockaddr_in specifies the address of the socket

    //for TCP/IP sockets. Other protocols use similar structures.

    sockaddr_in local;

    //WSAStartup initializes the program for calling WinSock.

    //The first parameter specifies the highest version of the 

    //WinSock specification, the program is allowed to use.

    int wsaret=WSAStartup(0x101,&wsaData);

    //WSAStartup returns zero on success.

    //If it fails we exit.

    if(wsaret!=0)
    {
        return 0;
    }

    //Now we populate the sockaddr_in structure

    local.sin_family=AF_INET; //Address family

    local.sin_addr.s_addr=INADDR_ANY; //Wild card IP address

    local.sin_port=htons((u_short)20248); //port to use

    //the socket function creates our SOCKET

    server=socket(AF_INET,SOCK_STREAM,0);

    //If the socket() function fails we exit

    if(server==INVALID_SOCKET)
    {
        return 0;
    }

    //bind links the socket we just created with the sockaddr_in 

    //structure. Basically it connects the socket with 

    //the local address and a specified port.

    //If it returns non-zero quit, as this indicates error

    if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
    {
        return 0;
    }

    //listen instructs the socket to listen for incoming 

    //connections from clients. The second arg is the backlog

    if(listen(server,10)!=0)
    {
        return 0;
    }

    //we will need variables to hold the client socket.

    //thus we declare them here.

    SOCKET client;
    sockaddr_in from;
    int fromlen=sizeof(from);

    while(true)//we are looping endlessly

    {
        char temp[512];

        //accept() will accept an incoming

        //client connection

        client=accept(server,
            (struct sockaddr*)&from,&fromlen);
    
        sprintf(temp,"Your IP is %s/r/n",inet_ntoa(from.sin_addr));

        //we simply send this string to the client

        send(client,temp,strlen(temp),0);
        cout << "Connection from " << inet_ntoa(from.sin_addr) <<"/r/n";
    
        //close the client socket

        closesocket(client);

    }

    //closesocket() closes the socket and releases the socket descriptor

    closesocket(server);

    //originally this function probably had some use

    //currently this is just for backward compatibility

    //but it is safer to call it as I still believe some

    //implementations use this to terminate use of WS2_32.DLL 

    WSACleanup();

    return 0;
}