一、简单的TCP服务器

转载 2006年05月29日 13:09:00

一、简单的TCP服务器


介绍

WinSock API是一套供Microsoft Windows操作系统使用的套接字程序库,它最初基于Berkeley套接字,但是其中加入了一些Microsoft的特殊改动。在这篇文章中,我要试着给你介绍如何使用WinSock来进行套接字程序设计,并假设你没有在任何操作系统上进行过网络编程的经验。
如果你只有一台单独的机器,那么不用着急,你仍然可以进行WinSock程序设计。你可以使用名为localhost的本地回环地址,它的IP地址是127.0.0.1。这样一来,如果你在机器上运行了一个TCP服务器,那么同一机器上的客户端程序就可以使用这个回环地址连接到服务器了。

简单的TCP服务器

在本文中,我将通过一个简单的TCP服务器来向你介绍WinSock,我们会一步一步地创建这个程序。但是,在我们开始之前,你还必须做一些事情,这样我们才能为开始我们的WinSock程序做好准备。
·首先,使用VC++ 6.0应用程序向导来创建一个Win32 console application。
·选择add support for MFC选项。
·打开stdafx.h文件,并添加这一行:#include <winsock2.h>。
·选择Project-Settings-Link,并在库模块列表中加入ws2_32.lib。

main函数

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

    cout << "Press ESCAPE to terminate program/r/n";
    AfxBeginThread(ServerThread,0);
    while(_getch()!=27);

    return nRetCode;
}

我们在main()中所做的是开启一个线程,然后对一个_getch()调用进行循环。_getch()仅仅是等待一个键的按下,并返回这个读入字符的ASCII值。我们一直循环,直到返回27这个值为止——既然27是ESCAPE键的ASCII码。你可能想知道的是,即使我们按下了ESCAPE,我们开启的线程也还会是活动的状态。不用为这些事情担心,因为当main()返回的时候,进程就会被终止,主线程开启的线程也会被突然终止。

ServerThread函数

现在我所要做的事情就是把我们的ServerThread函数列出来,并使用代码的注释来解释相关的代码行做了些什么。我们的TCP服务器主要做的事情是监听端口20248,这个数字也就是我在Code Project的成员ID。这个过程中的事件是:当客户端连接的时候,服务器将会向客户端发回一条消息告知它的IP地址,然后关闭连接并继续接收20248端口的连接。它还会在运行的控制台上打印出连接来自的IP地址。总而言之,你可能会认为这是一个绝对没用的程序。事实上,你们中的有些人甚至可能会认为它和Windows中的SNDREC32.EXE一样没用。我说,你们也忒苛刻了吧。

UINT  ServerThread(LPVOID pParam)
{
    cout << "Starting up TCP server/r/n";

    // SOCKET其实是unsigned int的一个typedef。
    // 在Unix中,套接字句柄就像文件句柄一样,都是unsigned int。
    // 既然在Windows下这些不是真的,那么我们就定义了一种新的数据类型,名为SOCKET。
    SOCKET server;

    // WSADATA是一个struct,WSAStartup的调用将会填充之。
    WSADATA wsaData;

    // sockaddr_in为TCP/IP套接字指定了套接字的地址。
    // 其它的协议都使用相似的结构。
    sockaddr_in local;

    // WSAStartup为程序调用WinSock进行了初始化。
    // 第一个参数指定了程序允许使用的WinSock规范的最高版本。
    int wsaret=WSAStartup(0x101,&wsaData);

    // 如果成功,WSAStartup返回零。
    // 如果失败,我们就退出。
    if(wsaret!=0)
    {
        return 0;
    }

    // 现在我们来为sockaddr_in结构赋值。
    local.sin_family=AF_INET; // 地址族
    local.sin_addr.s_addr=INADDR_ANY; // 网际IP地址
    local.sin_port=htons((u_short)20248); // 使用的端口

    // 由socket函数创建我们的SOCKET。
    server=socket(AF_INET,SOCK_STREAM,0);

    // 如果socket()函数失败,我们就退出。
    if(server==INVALID_SOCKET)
    {
        return 0;
    }

    // bind将我们刚创建的套接字和sockaddr_in结构联系起来。
    // 它主要使用本地地址及一个特定的端口来连接套接字。
    // 如果它返回非零值,就表示出现错误。
    if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
    {
        return 0;
    }

    // listen命令套接字监听来自客户端的连接。
    // 第二个参数是最大连接数。
    if(listen(server,10)!=0)
    {
        return 0;
    }

    // 我们需要一些变量来保存客户端的套接字,因此我们在此声明之。
    SOCKET client;
    sockaddr_in from;
    int fromlen=sizeof(from);

    while(true) // 无限循环
    {
        char temp[512];

        // accept()将会接收即将到来的客户端连接。
        client=accept(server,
            (struct sockaddr*)&from,&fromlen);

        sprintf(temp,"Your IP is %s/r/n",inet_ntoa(from.sin_addr));

        // 我们简单地向客户端发送这个字符串。
        send(client,temp,strlen(temp),0);
        cout << "Connection from " << inet_ntoa(from.sin_addr) <<"/r/n";

        // 关闭客户端套接字
        closesocket(client);

    }

    // closesocket()关闭套接字,并释放套接字描述符。
    closesocket(server);

    // 最初这个函数也许有些用处,现在保留它只是为了向后兼容。
    // 但是调用它可能会更安全,因为我相信某些实现会使用它来结束WS2_32.DLL的使用。
    WSACleanup();

    return 0;
}

测试

运行这个服务器,并在它运行的时候使用telnet来连接机器的20248端口。如果你是在同一台机器上使用,那么就连接到localhost。

示例输出

我们将会在服务器上看到这样的输出:

E:/work/Server/Debug>server
Press ESCAPE to terminate program
Starting up TCP server
Connection from 203.200.100.122
Connection from 127.0.0.1
E:/work/Server/Debug>

这是客户端得到的:

nish@sumida:~$ telnet 202.89.211.88 20248
Trying 202.89.211.88...
Connected to 202.89.211.88.
Escape character is '^]'.
Your IP is 203.200.100.122
Connection closed by foreign host.
nish@sumida:~$

总结

呃,在本文中你了解了如何创建一个简单的TCP服务器。在以后的文章中,我会给你一些更多的材料,你可以通过这些材料创建一个合适的TCP客户端。如果有谁对于编译这些代码有问题的话可以mail我,我会发给你一个压缩了的工程。谢谢您的阅读。

socket编程之简单的TCP服务器

一、socket编程 socket编程socket这个词可以表示很多概念: 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址+端口号”就称为socket...
  • LeetCode8023
  • LeetCode8023
  • 2016年08月06日 00:11
  • 1634

最简单服务器程序-TCP

服务器socket简单编程
  • u011922698
  • u011922698
  • 2017年02月15日 15:10
  • 226

Android网络应用之使用Scoket的Android客户端与TCP服务器的简单交互

Android网络应用之使用Scoket的Android客户端与TCP服务器的简单交互。
  • Wshshushu
  • Wshshushu
  • 2017年07月18日 20:51
  • 310

简单的,tcp多路复用,服务器的编写

#include #include #include #include #include #include #include #include #include #include #i...
  • FunkyFrog821951259
  • FunkyFrog821951259
  • 2016年12月11日 09:34
  • 291

实现TCP并发服务器之一(多进程)

下面用多进程方式实现一个TCP并发服务器,每当一个新的客户端连接时fork一个子进程去和它通信。(各种主流的web服务器都不是纯粹的多进程方式运行,比如apache在每个进程中都用多路复用方式,直到连...
  • ciaos
  • ciaos
  • 2012年07月04日 08:05
  • 1691

简单的TCP通信

服务端 #include #include #pragma comment(lib,"Ws2_32.lib") int main (void) { //加载套接字 WORD wVersion...
  • qq125096885
  • qq125096885
  • 2015年03月03日 14:56
  • 486

【Unix 网络编程】TCP 客户/服务器简单 Socket 程序

前面介绍了Socket 编程函数  在编写 Socket 程序之前还需要了解TCP连接是如何建立的。(参考资料《Unix 网络编程》) 建立一个 TCP 连接时会发生下述情形: 1. 服务器必须准备好...
  • yeswenqian
  • yeswenqian
  • 2014年03月20日 19:25
  • 1909

网络通信基础——MFC简单服务器客户端TCP通信

今天看了下MFC的网络通信基础,把一些心得写写。 首先看看TCP的通信流程   新建了两个工程,一个服务器工程,一个客户端工程,别的不说,直接从使用顺序来分析程序的调用关系。 首先点击服务器界...
  • xiaobaismiley
  • xiaobaismiley
  • 2011年10月22日 16:13
  • 7786

C#TCP服务器简单程序

参考网上的程序写的,仅仅都是概念,离实际应用还差十万八千里 using System.Net; using System.Net.Sockets; using System.Threading; 用...
  • fenglifeng1987
  • fenglifeng1987
  • 2013年12月20日 15:24
  • 10758

为初学者写的Winsock编程--一个简单的TCP服务器

介绍:WinSock(Windows Sockets)API是一个微软的windows系统接口编程库。它最初是基于Berkeley sockets。但是微软做了一些相应的改动。这里我试图简单的介绍一下...
  • diskonline
  • diskonline
  • 2008年04月02日 10:31
  • 645
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一、简单的TCP服务器
举报原因:
原因补充:

(最多只允许输入30个字)