C++ 网络模型实例

公司安排开始做服务器,没有接触过这些东西。从零开始学习。

项目是做个聊天系统客户端用flex,服务器用C++,让我先出Demo。

服务器部分参照Windows网络编程一书中的select例子,基本一样,只是把例子中的的单个回应消息改成了群发消息。

虽然我对select模型还不熟悉,但是我知道如果要在一个套接字上发消息就必须设置FD_SET    WriteSet,如果要在一个套接字上读消息就必须设置FD_SET    ReadSet,设置就是调用函数FD_SET(SOCKET S, FD_SET* Set)。

设置这个结构的目的相当于设置一张socket的列表,调用select函数,系统就会管理这个列表里面的socket。

接收消息的过程是循环遍历所有端口,如果有端口有数据接收进来而且这个端口存在于读的列表中,则去读取数据。

如果有端口要发送数据,则先看看这个端口是不是在写列表里,如果在则发送数据,否则不发。

select模式有端口数限制,FD_SIZE被定义为64,如果不去修改这个系统定义的宏,这FD_SET结构里面最多只能存64个端口。

我把它改成1000试过,可以接收1000个端口,不知道这样子会不会有什么问题。

经理的意见是改成完成端口。 

我又按照书上的完成端口示例弄出一个完成端口的服务器来,

我理解的完成端口就是把监听端口接收进来的客户端套接字绑定到一个完成端口上并开始接收消息,这个完成端口通过重叠IO机制来通知是否有消息到达。

完成端口在底层做的事情应该类似于select模型就是遍历所有和他绑在一起的端口。不知道我的理解对不对,恳请各位看到的指教。

我似懂非懂的看了几章感觉有用的东西 不过我感觉 这两本书是应该需要好好看完的,不会的东西太多了

另外的一些体会:

消息要先弄成消息队列,一个线程专门处理消息,一个线程专门处理接收数据,这样能保持处理消息的过程同步。

第一次搞服务器于是就第一次搞了多线程。线程同步比较重要,我看了Win32 多线程程序设计的几章帮助很大,很实用,一下子就解决问题了。我觉得这个水很深,继续摸中。

对我有帮助的资料:

windows 网络编程 8章 Winsock I/O方法

Win32 多线程程序设计 4章 同步控制 6章 overlapped I/O 在你身后变戏法

http://www.100ksw.com/jsj/dj/2/C++/3/187681.shtml(简单的socket例子)

http://tongjian.javaeye.com/blog/367252(字节序问题)

我把书上的代码贴贴上来好了,省得以后到处找。

select模型

 

  1. // Module Name: select.cpp   
  2. //   
  3. // Description:   
  4. //   
  5. //    This sample illustrates how to develop a simple echo server Winsock   
  6. //    application using the select() API I/O model. This sample is   
  7. //    implemented as a console-style application and simply prints   
  8. //    messages when connections are established and removed from the server.   
  9. //    The application listens for TCP connections on port 5150 and accepts   
  10. //    them as they arrive. When this application receives data from a client,   
  11. //    it simply echos (this is why we call it an echo server) the data back in   
  12. //    it's original form until the client closes the connection.   
  13. //   
  14. // Compile:   
  15. //   
  16. //    cl -o select select.cpp ws2_32.lib   
  17. //   
  18. // Command Line Options:   
  19. //   
  20. //    select.exe    
  21. //   
  22. //    Note: There are no command line options for this sample.   
  23. //   
  24. #include <winsock2.h>   
  25. #include <windows.h>   
  26. #include <stdio.h>   
  27.   
  28. #define PORT 5150   
  29. #define DATA_BUFSIZE 8192   
  30.   
  31. typedef struct _SOCKET_INFORMATION {   
  32.    CHAR Buffer[DATA_BUFSIZE];   
  33.    WSABUF DataBuf;   
  34.    SOCKET Socket;   
  35.    OVERLAPPED Overlapped;   
  36.    DWORD BytesSEND;   
  37.    DWORD BytesRECV;   
  38. } SOCKET_INFORMATION, * LPSOCKET_INFORMATION;   
  39.   
  40. BOOL CreateSocketInformation(SOCKET s);   
  41. void FreeSocketInformation(DWORD Index);   
  42.   
  43. DWORD TotalSockets = 0;   
  44. LPSOCKET_INFORMATION SocketArray[FD_SETSIZE];   
  45.   
  46. void main(void)   
  47. {   
  48.    SOCKET ListenSocket;   
  49.    SOCKET AcceptSocket;   
  50.    SOCKADDR_IN InternetAddr;   
  51.    WSADATA wsaData;   
  52.    INT Ret;   
  53.    FD_SET WriteSet;   
  54.    FD_SET ReadSet;   
  55.    DWORD i;   
  56.    DWORD Total;   
  57.    ULONG NonBlock;   
  58.    DWORD Flags;   
  59.    DWORD SendBytes;   
  60.    DWORD RecvBytes;   
  61.   
  62.   
  63.    if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)   
  64.    {   
  65.       printf("WSAStartup() failed with error %d/n", Ret);   
  66.       WSACleanup();   
  67.       return;   
  68.    }   
  69.   
  70.    // Prepare a socket to listen for connections.   
  71.   
  72.    if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,   
  73.       WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)    
  74.    {   
  75.       printf("WSASocket() failed with error %d/n", WSAGetLastError());   
  76.       return;   
  77.    }   
  78.   
  79.    InternetAddr.sin_family = AF_INET;   
  80.    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);   
  81.    InternetAddr.sin_port = htons(PORT);   
  82.   
  83.    if (bind(ListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr))   
  84.       == SOCKET_ERROR)   
  85.    {   
  86.       printf("bind() failed with error %d/n", WSAGetLastError());   
  87.       return;   
  88.    }   
  89.   
  90.    if (listen(ListenSocket, 5))   
  91.    {   
  92.       printf("listen() failed with error %d/n", WSAGetLastError());   
  93.       return;   
  94.    }   
  95.   
  96.    // Change the socket mode on the listening socket from blocking to   
  97.    // non-block so the application will not block waiting for requests.   
  98.   
  99.    NonBlock = 1;   
  100.    if (ioctlsocket(ListenSocket, FIONBIO, &NonBlock) == SOCKET_ERROR)   
  101.    {   
  102.       printf("ioctlsocket() failed with error %d/n", WSAGetLastError());   
  103.       return;   
  104.    }   
  105.   
  106.    while(TRUE)   
  107.    {   
  108.       // Prepare the Read and Write socket sets for network I/O notification.   
  109.       FD_ZERO(&ReadSet);   
  110.       FD_ZERO(&WriteSet);   
  111.   
  112.       // Always look for connection attempts.   
  113.   
  114.       FD_SET(ListenSocket, &ReadSet);   
  115.   
  116.       // Set Read and Write notification for each socket based on the   
  117.       // current state the buffer.  If there is data remaining in the   
  118.       // buffer then set the Write set otherwise the Read set.   
  119.   
  120.       for (i = 0; i < TotalSockets; i++)   
  121.          if (SocketArray[i]->BytesRECV > SocketArray[i]->BytesSEND)   
  122.             FD_SET(SocketArray[i]->Socket, &WriteSet);   
  123.          else  
  124.             FD_SET(SocketArray[i]->Socket, &ReadSet);   
  125.   
  126.       if ((Total = select(0, &ReadSet, &WriteSet, NULL, NULL)) == SOCKET_ERROR)   
  127.       {   
  128.          printf("select() returned with error %d/n", WSAGetLastError());   
  129.          return;   
  130.       }   
  131.   
  132.       // Check for arriving connections on the listening socket.   
  133.       if (FD_ISSET(ListenSocket, &ReadSet))   
  134.       {   
  135.          Total--;   
  136.          if ((AcceptSocket = accept(ListenSocket, NULL, NULL)) != INVALID_SOCKET)   
  137.          {   
  138.   
  139.             // Set the accepted socket to non-blocking mode so the server will   
  140.             // not get caught in a blocked condition on WSASends   
  141.   
  142.             NonBlock = 1;   
  143.             if (ioctlsocket(AcceptSocket, FIONBIO, &NonBlock) == SOCKET_ERROR)   
  144.             {   
  145.                printf("ioctlsocket() failed with error %d/n", WSAGetLastError());   
  146.                return;   
  147.             }   
  148.   
  149.             if (CreateSocketInformation(AcceptSocket) == FALSE)   
  150.                return;   
  151.   
  152.          }   
  153.          else  
  154.          {         
  155.             if (WSAGetLastError() != WSAEWOULDBLOCK)   
  156.             {   
  157.                printf("accept() failed with error %d/n", WSAGetLastError());   
  158.                return;   
  159.             }   
  160.          }   
  161.       }   
  162.   
  163.       // Check each socket for Read and Write notification until the number   
  164.       // of sockets in Total is satisfied.   
  165.   
  166.       for (i = 0; Total > 0 && i < TotalSockets; i++)   
  167.       {   
  168.          LPSOCKET_INFORMATION SocketInfo = SocketArray[i];   
  169.   
  170.          // If the ReadSet is marked for this socket then this means data   
  171.          // is available to be read on the socket.   
  172.   
  173.          if (FD_ISSET(SocketInfo->Socket, &ReadSet))   
  174.          {   
  175.             Total--;   
  176.   
  177.             SocketInfo->DataBuf.buf = SocketInfo->Buffer;   
  178.             SocketInfo->DataBuf.len = DATA_BUFSIZE;   
  179.   
  180.             Flags = 0;   
  181.             if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,   
  182.                &Flags, NULL, NULL) == SOCKET_ERROR)   
  183.             {   
  184.                if (WSAGetLastError() != WSAEWOULDBLOCK)   
  185.                {   
  186.                   printf("WSARecv() failed with error %d/n", WSAGetLastError());   
  187.   
  188.                   FreeSocketInformation(i);   
  189.                }   
  190.   
  191.                continue;   
  192.             }    
  193.             else  
  194.             {   
  195.                SocketInfo->BytesRECV = RecvBytes;   
  196.   
  197.                // If zero bytes are received, this indicates the peer closed the   
  198.                // connection.   
  199.                if (RecvBytes == 0)   
  200.                {   
  201.                   FreeSocketInformation(i);   
  202.                   continue;   
  203.                }   
  204.             }   
  205.          }   
  206.   
  207.   
  208.          // If the WriteSet is marked on this socket then this means the internal   
  209.          // data buffers are available for more data.   
  210.   
  211.          if (FD_ISSET(SocketInfo->Socket, &WriteSet))   
  212.          {   
  213.             Total--;   
  214.   
  215.             SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;   
  216.             SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;   
  217.   
  218.             if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,   
  219.                NULL, NULL) == SOCKET_ERROR)   
  220.             {   
  221.                if (WSAGetLastError() != WSAEWOULDBLOCK)   
  222.                {   
  223.                   printf("WSASend() failed with error %d/n", WSAGetLastError());   
  224.   
  225.                   FreeSocketInformation(i);   
  226.                }   
  227.   
  228.                continue;   
  229.             }   
  230.             else  
  231.             {   
  232.                SocketInfo->BytesSEND += SendBytes;   
  233.   
  234.                if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)   
  235.                {   
  236.                   SocketInfo->BytesSEND = 0;   
  237.                   SocketInfo->BytesRECV = 0;   
  238.                }   
  239.             }   
  240.          }   
  241.       }   
  242.    }   
  243. }   
  244.   
  245. BOOL CreateSocketInformation(SOCKET s)   
  246. {   
  247.    LPSOCKET_INFORMATION SI;   
  248.          
  249.    printf("Accepted socket number %d/n", s);   
  250.   
  251.    if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,   
  252.       sizeof(SOCKET_INFORMATION))) == NULL)   
  253.    {   
  254.       printf("GlobalAlloc() failed with error %d/n", GetLastError());   
  255.       return FALSE;   
  256.    }   
  257.   
  258.    // Prepare SocketInfo structure for use.   
  259.   
  260.    SI->Socket = s;   
  261.    SI->BytesSEND = 0;   
  262.    SI->BytesRECV = 0;   
  263.   
  264.    SocketArray[TotalSockets] = SI;   
  265.   
  266.    TotalSockets++;   
  267.   
  268.    return(TRUE);   
  269. }   
  270.   
  271. void FreeSocketInformation(DWORD Index)   
  272. {   
  273.    LPSOCKET_INFORMATION SI = SocketArray[Index];   
  274.    DWORD i;   
  275.   
  276.    closesocket(SI->Socket);   
  277.   
  278.    printf("Closing socket number %d/n", SI->Socket);   
  279.   
  280.    GlobalFree(SI);   
  281.   
  282.    // Squash the socket array   
  283.   
  284.    for (i = Index; i < TotalSockets; i++)   
  285.    {   
  286.       SocketArray[i] = SocketArray[i + 1];   
  287.    }   
  288.   
  289.    TotalSockets--;   
  290. }  

  1. // Module Name: select.cpp  
  2. //  
  3. // Description:  
  4. //  
  5. //    This sample illustrates how to develop a simple echo server Winsock  
  6. //    application using the select() API I/O model. This sample is  
  7. //    implemented as a console-style application and simply prints  
  8. //    messages when connections are established and removed from the server.  
  9. //    The application listens for TCP connections on port 5150 and accepts  
  10. //    them as they arrive. When this application receives data from a client,  
  11. //    it simply echos (this is why we call it an echo server) the data back in  
  12. //    it's original form until the client closes the connection.  
  13. //  
  14. // Compile:  
  15. //  
  16. //    cl -o select select.cpp ws2_32.lib  
  17. //  
  18. // Command Line Options:  
  19. //  
  20. //    select.exe   
  21. //  
  22. //    Note: There are no command line options for this sample.  
  23. //  
  24. #include <winsock2.h>  
  25. #include <windows.h>  
  26. #include <stdio.h>  
  27.   
  28. #define PORT 5150  
  29. #define DATA_BUFSIZE 8192  
  30.   
  31. typedef struct _SOCKET_INFORMATION {  
  32.    CHAR Buffer[DATA_BUFSIZE];  
  33.    WSABUF DataBuf;  
  34.    SOCKET Socket;  
  35.    OVERLAPPED Overlapped;  
  36.    DWORD BytesSEND;  
  37.    DWORD BytesRECV;  
  38. } SOCKET_INFORMATION, * LPSOCKET_INFORMATION;  
  39.   
  40. BOOL CreateSocketInformation(SOCKET s);  
  41. void FreeSocketInformation(DWORD Index);  
  42.   
  43. DWORD TotalSockets = 0;  
  44. LPSOCKET_INFORMATION SocketArray[FD_SETSIZE];  
  45.   
  46. void main(void)  
  47. {  
  48.    SOCKET ListenSocket;  
  49.    SOCKET AcceptSocket;  
  50.    SOCKADDR_IN InternetAddr;  
  51.    WSADATA wsaData;  
  52.    INT Ret;  
  53.    FD_SET WriteSet;  
  54.    FD_SET ReadSet;  
  55.    DWORD i;  
  56.    DWORD Total;  
  57.    ULONG NonBlock;  
  58.    DWORD Flags;  
  59.    DWORD SendBytes;  
  60.    DWORD RecvBytes;  
  61.   
  62.   
  63.    if ((Ret = WSAStartup(0x0202,&wsaData)) != 0)  
  64.    {  
  65.       printf("WSAStartup() failed with error %d/n", Ret);  
  66.       WSACleanup();  
  67.       return;  
  68.    }  
  69.   
  70.    // Prepare a socket to listen for connections.  
  71.   
  72.    if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,  
  73.       WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)   
  74.    {  
  75.       printf("WSASocket() failed with error %d/n", WSAGetLastError());  
  76.       return;  
  77.    }  
  78.   
  79.    InternetAddr.sin_family = AF_INET;  
  80.    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  81.    InternetAddr.sin_port = htons(PORT);  
  82.   
  83.    if (bind(ListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr))  
  84.       == SOCKET_ERROR)  
  85.    {  
  86.       printf("bind() failed with error %d/n", WSAGetLastError());  
  87.       return;  
  88.    }  
  89.   
  90.    if (listen(ListenSocket, 5))  
  91.    {  
  92.       printf("listen() failed with error %d/n", WSAGetLastError());  
  93.       return;  
  94.    }  
  95.   
  96.    // Change the socket mode on the listening socket from blocking to  
  97.    // non-block so the application will not block waiting for requests.  
  98.   
  99.    NonBlock = 1;  
  100.    if (ioctlsocket(ListenSocket, FIONBIO, &NonBlock) == SOCKET_ERROR)  
  101.    {  
  102.       printf("ioctlsocket() failed with error %d/n", WSAGetLastError());  
  103.       return;  
  104.    }  
  105.   
  106.    while(TRUE)  
  107.    {  
  108.       // Prepare the Read and Write socket sets for network I/O notification.  
  109.       FD_ZERO(&ReadSet);  
  110.       FD_ZERO(&WriteSet);  
  111.   
  112.       // Always look for connection attempts.  
  113.   
  114.       FD_SET(ListenSocket, &ReadSet);  
  115.   
  116.       // Set Read and Write notification for each socket based on the  
  117.       // current state the buffer.  If there is data remaining in the  
  118.       // buffer then set the Write set otherwise the Read set.  
  119.   
  120.       for (i = 0; i < TotalSockets; i++)  
  121.          if (SocketArray[i]->BytesRECV > SocketArray[i]->BytesSEND)  
  122.             FD_SET(SocketArray[i]->Socket, &WriteSet);  
  123.          else  
  124.             FD_SET(SocketArray[i]->Socket, &ReadSet);  
  125.   
  126.       if ((Total = select(0, &ReadSet, &WriteSet, NULL, NULL)) == SOCKET_ERROR)  
  127.       {  
  128.          printf("select() returned with error %d/n", WSAGetLastError());  
  129.          return;  
  130.       }  
  131.   
  132.       // Check for arriving connections on the listening socket.  
  133.       if (FD_ISSET(ListenSocket, &ReadSet))  
  134.       {  
  135.          Total--;  
  136.          if ((AcceptSocket = accept(ListenSocket, NULL, NULL)) != INVALID_SOCKET)  
  137.          {  
  138.   
  139.             // Set the accepted socket to non-blocking mode so the server will  
  140.             // not get caught in a blocked condition on WSASends  
  141.   
  142.             NonBlock = 1;  
  143.             if (ioctlsocket(AcceptSocket, FIONBIO, &NonBlock) == SOCKET_ERROR)  
  144.             {  
  145.                printf("ioctlsocket() failed with error %d/n", WSAGetLastError());  
  146.                return;  
  147.             }  
  148.   
  149.             if (CreateSocketInformation(AcceptSocket) == FALSE)  
  150.                return;  
  151.   
  152.          }  
  153.          else  
  154.          {        
  155.             if (WSAGetLastError() != WSAEWOULDBLOCK)  
  156.             {  
  157.                printf("accept() failed with error %d/n", WSAGetLastError());  
  158.                return;  
  159.             }  
  160.          }  
  161.       }  
  162.   
  163.       // Check each socket for Read and Write notification until the number  
  164.       // of sockets in Total is satisfied.  
  165.   
  166.       for (i = 0; Total > 0 && i < TotalSockets; i++)  
  167.       {  
  168.          LPSOCKET_INFORMATION SocketInfo = SocketArray[i];  
  169.   
  170.          // If the ReadSet is marked for this socket then this means data  
  171.          // is available to be read on the socket.  
  172.   
  173.          if (FD_ISSET(SocketInfo->Socket, &ReadSet))  
  174.          {  
  175.             Total--;  
  176.   
  177.             SocketInfo->DataBuf.buf = SocketInfo->Buffer;  
  178.             SocketInfo->DataBuf.len = DATA_BUFSIZE;  
  179.   
  180.             Flags = 0;  
  181.             if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,  
  182.                &Flags, NULL, NULL) == SOCKET_ERROR)  
  183.             {  
  184.                if (WSAGetLastError() != WSAEWOULDBLOCK)  
  185.                {  
  186.                   printf("WSARecv() failed with error %d/n", WSAGetLastError());  
  187.   
  188.                   FreeSocketInformation(i);  
  189.                }  
  190.   
  191.                continue;  
  192.             }   
  193.             else  
  194.             {  
  195.                SocketInfo->BytesRECV = RecvBytes;  
  196.   
  197.                // If zero bytes are received, this indicates the peer closed the  
  198.                // connection.  
  199.                if (RecvBytes == 0)  
  200.                {  
  201.                   FreeSocketInformation(i);  
  202.                   continue;  
  203.                }  
  204.             }  
  205.          }  
  206.   
  207.   
  208.          // If the WriteSet is marked on this socket then this means the internal  
  209.          // data buffers are available for more data.  
  210.   
  211.          if (FD_ISSET(SocketInfo->Socket, &WriteSet))  
  212.          {  
  213.             Total--;  
  214.   
  215.             SocketInfo->DataBuf.buf = SocketInfo->Buffer + SocketInfo->BytesSEND;  
  216.             SocketInfo->DataBuf.len = SocketInfo->BytesRECV - SocketInfo->BytesSEND;  
  217.   
  218.             if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &SendBytes, 0,  
  219.                NULL, NULL) == SOCKET_ERROR)  
  220.             {  
  221.                if (WSAGetLastError() != WSAEWOULDBLOCK)  
  222.                {  
  223.                   printf("WSASend() failed with error %d/n", WSAGetLastError());  
  224.   
  225.                   FreeSocketInformation(i);  
  226.                }  
  227.   
  228.                continue;  
  229.             }  
  230.             else  
  231.             {  
  232.                SocketInfo->BytesSEND += SendBytes;  
  233.   
  234.                if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)  
  235.                {  
  236.                   SocketInfo->BytesSEND = 0;  
  237.                   SocketInfo->BytesRECV = 0;  
  238.                }  
  239.             }  
  240.          }  
  241.       }  
  242.    }  
  243. }  
  244.   
  245. BOOL CreateSocketInformation(SOCKET s)  
  246. {  
  247.    LPSOCKET_INFORMATION SI;  
  248.         
  249.    printf("Accepted socket number %d/n", s);  
  250.   
  251.    if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,  
  252.       sizeof(SOCKET_INFORMATION))) == NULL)  
  253.    {  
  254.       printf("GlobalAlloc() failed with error %d/n", GetLastError());  
  255.       return FALSE;  
  256.    }  
  257.   
  258.    // Prepare SocketInfo structure for use.  
  259.   
  260.    SI->Socket = s;  
  261.    SI->BytesSEND = 0;  
  262.    SI->BytesRECV = 0;  
  263.   
  264.    SocketArray[TotalSockets] = SI;  
  265.   
  266.    TotalSockets++;  
  267.   
  268.    return(TRUE);  
  269. }  
  270.   
  271. void FreeSocketInformation(DWORD Index)  
  272. {  
  273.    LPSOCKET_INFORMATION SI = SocketArray[Index];  
  274.    DWORD i;  
  275.   
  276.    closesocket(SI->Socket);  
  277.   
  278.    printf("Closing socket number %d/n", SI->Socket);  
  279.   
  280.    GlobalFree(SI);  
  281.   
  282.    // Squash the socket array  
  283.   
  284.    for (i = Index; i < TotalSockets; i++)  
  285.    {  
  286.       SocketArray[i] = SocketArray[i + 1];  
  287.    }  
  288.   
  289.    TotalSockets--;  
  290. }  

 

完成端口模型

 

  1. // Module Name: iocmplt.cpp   
  2. //   
  3. // Description:   
  4. //   
  5. //    This sample illustrates how to develop a simple echo server Winsock   
  6. //    application using the completeion port I/O model. This    
  7. //    sample is implemented as a console-style application and simply prints   
  8. //    messages when connections are established and removed from the server.   
  9. //    The application listens for TCP connections on port 5150 and accepts them   
  10. //    as they arrive. When this application receives data from a client, it   
  11. //    simply echos (this is why we call it an echo server) the data back in   
  12. //    it's original form until the client closes the connection.   
  13. //   
  14. // Compile:   
  15. //   
  16. //    cl -o iocmplt iocmplt.cpp ws2_32.lib   
  17. //   
  18. // Command Line Options:   
  19. //   
  20. //    iocmplt.exe    
  21. //   
  22. //    Note: There are no command line options for this sample.   
  23.   
  24. #include <winsock2.h>   
  25. #include <windows.h>   
  26. #include <stdio.h>   
  27.   
  28. #define PORT 5150   
  29. #define DATA_BUFSIZE 8192   
  30.   
  31. typedef struct  
  32. {   
  33.    OVERLAPPED Overlapped;   
  34.    WSABUF DataBuf;   
  35.    CHAR Buffer[DATA_BUFSIZE];   
  36.    DWORD BytesSEND;   
  37.    DWORD BytesRECV;   
  38. } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;   
  39.   
  40.   
  41. typedef struct    
  42. {   
  43.    SOCKET Socket;   
  44. } PER_HANDLE_DATA, * LPPER_HANDLE_DATA;   
  45.   
  46.   
  47. DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);   
  48.   
  49. void main(void)   
  50. {   
  51.    SOCKADDR_IN InternetAddr;   
  52.    SOCKET Listen;   
  53.    SOCKET Accept;   
  54.    HANDLE CompletionPort;   
  55.    SYSTEM_INFO SystemInfo;   
  56.    LPPER_HANDLE_DATA PerHandleData;   
  57.    LPPER_IO_OPERATION_DATA PerIoData;   
  58.    int i;   
  59.    DWORD RecvBytes;   
  60.    DWORD Flags;   
  61.    DWORD ThreadID;   
  62.    WSADATA wsaData;   
  63.    DWORD Ret;   
  64.   
  65.    if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)   
  66.    {   
  67.       printf("WSAStartup failed with error %d/n", Ret);   
  68.       return;   
  69.    }   
  70.   
  71.    // Setup an I/O completion port.   
  72.   
  73.    if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)   
  74.    {   
  75.       printf( "CreateIoCompletionPort failed with error: %d/n", GetLastError());   
  76.       return;   
  77.    }   
  78.   
  79.    // Determine how many processors are on the system.   
  80.   
  81.    GetSystemInfo(&SystemInfo);   
  82.   
  83.    // Create worker threads based on the number of processors available on the   
  84.    // system. Create two worker threads for each processor.   
  85.   
  86.    for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)   
  87.    {   
  88.       HANDLE ThreadHandle;   
  89.   
  90.       // Create a server worker thread and pass the completion port to the thread.   
  91.   
  92.       if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,   
  93.          0, &ThreadID)) == NULL)   
  94.       {   
  95.          printf("CreateThread() failed with error %d/n", GetLastError());   
  96.          return;   
  97.       }   
  98.   
  99.       // Close the thread handle   
  100.       CloseHandle(ThreadHandle);   
  101.    }   
  102.   
  103.    // Create a listening socket   
  104.   
  105.    if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,   
  106.       WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)   
  107.    {   
  108.       printf("WSASocket() failed with error %d/n", WSAGetLastError());   
  109.       return;   
  110.    }    
  111.   
  112.    InternetAddr.sin_family = AF_INET;   
  113.    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);   
  114.    InternetAddr.sin_port = htons(PORT);   
  115.   
  116.    if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)   
  117.    {   
  118.       printf("bind() failed with error %d/n", WSAGetLastError());   
  119.       return;   
  120.    }   
  121.   
  122.    // Prepare socket for listening   
  123.   
  124.    if (listen(Listen, 5) == SOCKET_ERROR)   
  125.    {   
  126.       printf("listen() failed with error %d/n", WSAGetLastError());   
  127.       return;   
  128.    }   
  129.   
  130.    // Accept connections and assign to the completion port.   
  131.   
  132.    while(TRUE)   
  133.    {   
  134.       if ((Accept = WSAAccept(Listen, NULL, NULL, NULL, 0)) == SOCKET_ERROR)   
  135.       {   
  136.          printf("WSAAccept() failed with error %d/n", WSAGetLastError());   
  137.          return;   
  138.       }   
  139.   
  140.       // Create a socket information structure to associate with the socket   
  141.       if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,    
  142.          sizeof(PER_HANDLE_DATA))) == NULL)   
  143.       {   
  144.          printf("GlobalAlloc() failed with error %d/n", GetLastError());   
  145.          return;   
  146.       }   
  147.   
  148.       // Associate the accepted socket with the original completion port.   
  149.   
  150.       printf("Socket number %d connected/n", Accept);   
  151.       PerHandleData->Socket = Accept;   
  152.   
  153.       if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData,   
  154.          0) == NULL)   
  155.       {   
  156.          printf("CreateIoCompletionPort failed with error %d/n", GetLastError());   
  157.          return;   
  158.       }   
  159.   
  160.       // Create per I/O socket information structure to associate with the    
  161.       // WSARecv call below.   
  162.   
  163.       if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,          sizeof(PER_IO_OPERATION_DATA))) == NULL)   
  164.       {   
  165.          printf("GlobalAlloc() failed with error %d/n", GetLastError());   
  166.          return;   
  167.       }   
  168.   
  169.       ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));   
  170.       PerIoData->BytesSEND = 0;   
  171.       PerIoData->BytesRECV = 0;   
  172.       PerIoData->DataBuf.len = DATA_BUFSIZE;   
  173.       PerIoData->DataBuf.buf = PerIoData->Buffer;   
  174.   
  175.       Flags = 0;   
  176.       if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,   
  177.          &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)   
  178.       {   
  179.          if (WSAGetLastError() != ERROR_IO_PENDING)   
  180.          {   
  181.             printf("WSARecv() failed with error %d/n", WSAGetLastError());   
  182.             return;   
  183.          }   
  184.       }   
  185.    }   
  186. }   
  187.   
  188. DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)   
  189. {   
  190.    HANDLE CompletionPort = (HANDLE) CompletionPortID;   
  191.    DWORD BytesTransferred;   
  192.    LPOVERLAPPED Overlapped;   
  193.    LPPER_HANDLE_DATA PerHandleData;   
  194.    LPPER_IO_OPERATION_DATA PerIoData;   
  195.    DWORD SendBytes, RecvBytes;   
  196.    DWORD Flags;   
  197.       
  198.    while(TRUE)   
  199.    {   
  200.            
  201.       if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,   
  202.          (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)   
  203.       {   
  204.          printf("GetQueuedCompletionStatus failed with error %d/n", GetLastError());   
  205.          return 0;   
  206.       }   
  207.   
  208.   
  209.       // First check to see if an error has occured on the socket and if so   
  210.       // then close the socket and cleanup the SOCKET_INFORMATION structure   
  211.       // associated with the socket.   
  212.   
  213.       if (BytesTransferred == 0)   
  214.       {   
  215.          printf("Closing socket %d/n", PerHandleData->Socket);   
  216.   
  217.          if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)   
  218.          {   
  219.             printf("closesocket() failed with error %d/n", WSAGetLastError());   
  220.             return 0;   
  221.          }   
  222.   
  223.          GlobalFree(PerHandleData);   
  224.          GlobalFree(PerIoData);   
  225.          continue;   
  226.       }   
  227.   
  228.       // Check to see if the BytesRECV field equals zero. If this is so, then   
  229.       // this means a WSARecv call just completed so update the BytesRECV field   
  230.       // with the BytesTransferred value from the completed WSARecv() call.   
  231.   
  232.       if (PerIoData->BytesRECV == 0)   
  233.       {   
  234.          PerIoData->BytesRECV = BytesTransferred;   
  235.          PerIoData->BytesSEND = 0;   
  236.       }   
  237.       else  
  238.       {   
  239.          PerIoData->BytesSEND += BytesTransferred;   
  240.       }   
  241.   
  242.       if (PerIoData->BytesRECV > PerIoData->BytesSEND)   
  243.       {   
  244.   
  245.          // Post another WSASend() request.   
  246.          // Since WSASend() is not gauranteed to send all of the bytes requested,   
  247.          // continue posting WSASend() calls until all received bytes are sent.   
  248.   
  249.          ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));   
  250.   
  251.          PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;   
  252.          PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;   
  253.   
  254.          if (WSASend(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, 0,   
  255.             &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)   
  256.          {   
  257.             if (WSAGetLastError() != ERROR_IO_PENDING)   
  258.             {   
  259.                printf("WSASend() failed with error %d/n", WSAGetLastError());   
  260.                return 0;   
  261.             }   
  262.          }   
  263.       }   
  264.       else  
  265.       {   
  266.          PerIoData->BytesRECV = 0;   
  267.   
  268.          // Now that there are no more bytes to send post another WSARecv() request.   
  269.   
  270.          Flags = 0;   
  271.          ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));   
  272.   
  273.          PerIoData->DataBuf.len = DATA_BUFSIZE;   
  274.          PerIoData->DataBuf.buf = PerIoData->Buffer;   
  275.   
  276.          if (WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,   
  277.             &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)   
  278.          {   
  279.             if (WSAGetLastError() != ERROR_IO_PENDING)   
  280.             {   
  281.                printf("WSARecv() failed with error %d/n", WSAGetLastError());   
  282.                return 0;   
  283.             }   
  284.          }   
  285.       }   
  286.    }   
  287. }  

  1. // Module Name: iocmplt.cpp  
  2. //  
  3. // Description:  
  4. //  
  5. //    This sample illustrates how to develop a simple echo server Winsock  
  6. //    application using the completeion port I/O model. This   
  7. //    sample is implemented as a console-style application and simply prints  
  8. //    messages when connections are established and removed from the server.  
  9. //    The application listens for TCP connections on port 5150 and accepts them  
  10. //    as they arrive. When this application receives data from a client, it  
  11. //    simply echos (this is why we call it an echo server) the data back in  
  12. //    it's original form until the client closes the connection.  
  13. //  
  14. // Compile:  
  15. //  
  16. //    cl -o iocmplt iocmplt.cpp ws2_32.lib  
  17. //  
  18. // Command Line Options:  
  19. //  
  20. //    iocmplt.exe   
  21. //  
  22. //    Note: There are no command line options for this sample.  
  23.   
  24. #include <winsock2.h>  
  25. #include <windows.h>  
  26. #include <stdio.h>  
  27.   
  28. #define PORT 5150  
  29. #define DATA_BUFSIZE 8192  
  30.   
  31. typedef struct  
  32. {  
  33.    OVERLAPPED Overlapped;  
  34.    WSABUF DataBuf;  
  35.    CHAR Buffer[DATA_BUFSIZE];  
  36.    DWORD BytesSEND;  
  37.    DWORD BytesRECV;  
  38. } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;  
  39.   
  40.   
  41. typedef struct   
  42. {  
  43.    SOCKET Socket;  
  44. } PER_HANDLE_DATA, * LPPER_HANDLE_DATA;  
  45.   
  46.   
  47. DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);  
  48.   
  49. void main(void)  
  50. {  
  51.    SOCKADDR_IN InternetAddr;  
  52.    SOCKET Listen;  
  53.    SOCKET Accept;  
  54.    HANDLE CompletionPort;  
  55.    SYSTEM_INFO SystemInfo;  
  56.    LPPER_HANDLE_DATA PerHandleData;  
  57.    LPPER_IO_OPERATION_DATA PerIoData;  
  58.    int i;  
  59.    DWORD RecvBytes;  
  60.    DWORD Flags;  
  61.    DWORD ThreadID;  
  62.    WSADATA wsaData;  
  63.    DWORD Ret;  
  64.   
  65.    if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)  
  66.    {  
  67.       printf("WSAStartup failed with error %d/n", Ret);  
  68.       return;  
  69.    }  
  70.   
  71.    // Setup an I/O completion port.  
  72.   
  73.    if ((CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL)  
  74.    {  
  75.       printf( "CreateIoCompletionPort failed with error: %d/n", GetLastError());  
  76.       return;  
  77.    }  
  78.   
  79.    // Determine how many processors are on the system.  
  80.   
  81.    GetSystemInfo(&SystemInfo);  
  82.   
  83.    // Create worker threads based on the number of processors available on the  
  84.    // system. Create two worker threads for each processor.  
  85.   
  86.    for(i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)  
  87.    {  
  88.       HANDLE ThreadHandle;  
  89.   
  90.       // Create a server worker thread and pass the completion port to the thread.  
  91.   
  92.       if ((ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, CompletionPort,  
  93.          0, &ThreadID)) == NULL)  
  94.       {  
  95.          printf("CreateThread() failed with error %d/n", GetLastError());  
  96.          return;  
  97.       }  
  98.   
  99.       // Close the thread handle  
  100.       CloseHandle(ThreadHandle);  
  101.    }  
  102.   
  103.    // Create a listening socket  
  104.   
  105.    if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,  
  106.       WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)  
  107.    {  
  108.       printf("WSASocket() failed with error %d/n", WSAGetLastError());  
  109.       return;  
  110.    }   
  111.   
  112.    InternetAddr.sin_family = AF_INET;  
  113.    InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  114.    InternetAddr.sin_port = htons(PORT);  
  115.   
  116.    if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)  
  117.    {  
  118.       printf("bind() failed with error %d/n", WSAGetLastError());  
  119.       return;  
  120.    }  
  121.   
  122.    // Prepare socket for listening  
  123.   
  124.    if (listen(Listen, 5) == SOCKET_ERROR)  
  125.    {  
  126.       printf("listen() failed with error %d/n", WSAGetLastError());  
  127.       return;  
  128.    }  
  129.   
  130.    // Accept connections and assign to the completion port.  
  131.   
  132.    while(TRUE)  
  133.    {  
  134.       if ((Accept = WSAAccept(Listen, NULL, NULL, NULL, 0)) == SOCKET_ERROR)  
  135.       {  
  136.          printf("WSAAccept() failed with error %d/n", WSAGetLastError());  
  137.          return;  
  138.       }  
  139.   
  140.       // Create a socket information structure to associate with the socket  
  141.       if ((PerHandleData = (LPPER_HANDLE_DATA) GlobalAlloc(GPTR,   
  142.          sizeof(PER_HANDLE_DATA))) == NULL)  
  143.       {  
  144.          printf("GlobalAlloc() failed with error %d/n", GetLastError());  
  145.          return;  
  146.       }  
  147.   
  148.       // Associate the accepted socket with the original completion port.  
  149.   
  150.       printf("Socket number %d connected/n", Accept);  
  151.       PerHandleData->Socket = Accept;  
  152.   
  153.       if (CreateIoCompletionPort((HANDLE) Accept, CompletionPort, (DWORD) PerHandleData,  
  154.          0) == NULL)  
  155.       {  
  156.          printf("CreateIoCompletionPort failed with error %d/n", GetLastError());  
  157.          return;  
  158.       }  
  159.   
  160.       // Create per I/O socket information structure to associate with the   
  161.       // WSARecv call below.  
  162.   
  163.       if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc(GPTR,          sizeof(PER_IO_OPERATION_DATA))) == NULL)  
  164.       {  
  165.          printf("GlobalAlloc() failed with error %d/n", GetLastError());  
  166.          return;  
  167.       }  
  168.   
  169.       ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));  
  170.       PerIoData->BytesSEND = 0;  
  171.       PerIoData->BytesRECV = 0;  
  172.       PerIoData->DataBuf.len = DATA_BUFSIZE;  
  173.       PerIoData->DataBuf.buf = PerIoData->Buffer;  
  174.   
  175.       Flags = 0;  
  176.       if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,  
  177.          &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)  
  178.       {  
  179.          if (WSAGetLastError() != ERROR_IO_PENDING)  
  180.          {  
  181.             printf("WSARecv() failed with error %d/n", WSAGetLastError());  
  182.             return;  
  183.          }  
  184.       }  
  185.    }  
  186. }  
  187.   
  188. DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)  
  189. {  
  190.    HANDLE CompletionPort = (HANDLE) CompletionPortID;  
  191.    DWORD BytesTransferred;  
  192.    LPOVERLAPPED Overlapped;  
  193.    LPPER_HANDLE_DATA PerHandleData;  
  194.    LPPER_IO_OPERATION_DATA PerIoData;  
  195.    DWORD SendBytes, RecvBytes;  
  196.    DWORD Flags;  
  197.      
  198.    while(TRUE)  
  199.    {  
  200.           
  201.       if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,  
  202.          (LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)  
  203.       {  
  204.          printf("GetQueuedCompletionStatus failed with error %d/n", GetLastError());  
  205.          return 0;  
  206.       }  
  207.   
  208.   
  209.       // First check to see if an error has occured on the socket and if so  
  210.       // then close the socket and cleanup the SOCKET_INFORMATION structure  
  211.       // associated with the socket.  
  212.   
  213.       if (BytesTransferred == 0)  
  214.       {  
  215.          printf("Closing socket %d/n", PerHandleData->Socket);  
  216.   
  217.          if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)  
  218.          {  
  219.             printf("closesocket() failed with error %d/n", WSAGetLastError());  
  220.             return 0;  
  221.          }  
  222.   
  223.          GlobalFree(PerHandleData);  
  224.          GlobalFree(PerIoData);  
  225.          continue;  
  226.       }  
  227.   
  228.       // Check to see if the BytesRECV field equals zero. If this is so, then  
  229.       // this means a WSARecv call just completed so update the BytesRECV field  
  230.       // with the BytesTransferred value from the completed WSARecv() call.  
  231.   
  232.       if (PerIoData->BytesRECV == 0)  
  233.       {  
  234.          PerIoData->BytesRECV = BytesTransferred;  
  235.          PerIoData->BytesSEND = 0;  
  236.       }  
  237.       else  
  238.       {  
  239.          PerIoData->BytesSEND += BytesTransferred;  
  240.       }  
  241.   
  242.       if (PerIoData->BytesRECV > PerIoData->BytesSEND)  
  243.       {  
  244.   
  245.          // Post another WSASend() request.  
  246.          // Since WSASend() is not gauranteed to send all of the bytes requested,  
  247.          // continue posting WSASend() calls until all received bytes are sent.  
  248.   
  249.          ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));  
  250.   
  251.          PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;  
  252.          PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;  
  253.   
  254.          if (WSASend(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, 0,  
  255.             &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)  
  256.          {  
  257.             if (WSAGetLastError() != ERROR_IO_PENDING)  
  258.             {  
  259.                printf("WSASend() failed with error %d/n", WSAGetLastError());  
  260.                return 0;  
  261.             }  
  262.          }  
  263.       }  
  264.       else  
  265.       {  
  266.          PerIoData->BytesRECV = 0;  
  267.   
  268.          // Now that there are no more bytes to send post another WSARecv() request.  
  269.   
  270.          Flags = 0;  
  271.          ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));  
  272.   
  273.          PerIoData->DataBuf.len = DATA_BUFSIZE;  
  274.          PerIoData->DataBuf.buf = PerIoData->Buffer;  
  275.   
  276.          if (WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,  
  277.             &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)  
  278.          {  
  279.             if (WSAGetLastError() != ERROR_IO_PENDING)  
  280.             {  
  281.                printf("WSARecv() failed with error %d/n", WSAGetLastError());  
  282.                return 0;  
  283.             }  
  284.          }  
  285.       }  
  286.    }  
  287. }  

 

从flex过来的数据中取int

 

  1. void memcpyHtol(int &des, char* &str)   
  2. {   
  3.     int len = sizeof(des);   
  4.     memcpy(&des, str, len);   
  5.     des = htonl(des);   
  6.     str += len;   
  7. }  

  1. void memcpyHtol(int &des, char* &str)  
  2. {  
  3.     int len = sizeof(des);  
  4.     memcpy(&des, str, len);  
  5.     des = htonl(des);  
  6.     str += len;  
  7. }  

 

//---------------------------------------------------分割线-----------------------------------------//

flex客户端代码

chat.mxml:

 

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="388" height="376" applicationComplete="init()">  
  3.     <mx:Script>  
  4.         <!--[CDATA[   
  5.             import flash.net.Socket;   
  6.             import flash.utils.ByteArray;   
  7.             private var socket:Socket=new Socket();   
  8.                
  9.             private var strInfor:String = "";   
  10.             private var m_name:String = "";   
  11.             private var m_msg:String = "";   
  12.                
  13.             internal function init():void   
  14.             {   
  15.                 m_textarea.text = "";   
  16.             }   
  17.             internal function onLogin():void   
  18.             {   
  19.                 socket.connect("127.0.0.1",int(m_port_input.text));//执行连接   
  20.                 socket.addEventListener(Event.CONNECT,funConnect);   
  21.                 socket.addEventListener(Event.CLOSE,funClose);   
  22.                 socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);   
  23.             }   
  24.             internal function onSend():void   
  25.             {   
  26.                 m_msg = m_text_input.text;   
  27.                 socket.writeMultiByte(m_msg, "utf-8");   
  28.                 socket.flush();   
  29.             }   
  30.             internal function funConnect(event:Event):void   
  31.             {   
  32.                 funUpdateText("连接成功!");   
  33.                 m_text_input.enabled = true;   
  34.                 send_btn.enabled = true;   
  35.             }   
  36.             internal function funClose(event:Event):void   
  37.             {   
  38.                 funUpdateText("连接关闭!");   
  39.             }   
  40.             internal function funSocket(event:ProgressEvent):void   
  41.             {   
  42.                 var msg:String="";   
  43.                 while(socket.bytesAvailable)   
  44.                  {   
  45.                         msg+=socket.readMultiByte(socket.bytesAvailable,"utf8");   
  46.                         var arr:Array=msg.split('n');   
  47.                         for(var i:int=0;i<arr.length;i++)   
  48.                         {   
  49.                             if(arr[i].length>1)   
  50.                             {   
  51.                                 var myPattern:RegExp=/r/;   
  52.                                 arr[i]=arr[i].replace(myPattern,'');   
  53.                                 funUpdateText(arr[i]);   
  54.                             }   
  55.                         }   
  56.                 }   
  57.                 m_text_input.text = "";   
  58.             }   
  59.                
  60.             internal function funUpdateText(str:String):void   
  61.             {   
  62.                 strInfor += str + "/n";   
  63.                 m_textarea.text = strInfor;   
  64.                 m_textaream_textarea.verticalScrollPosition = m_textarea.maxVerticalScrollPosition;//滚动到最下面   
  65.             }   
  66.                
  67.             internal function ClearScreen():void   
  68.             {   
  69.                 strInfor = "";   
  70.                 m_textarea.text = "";   
  71.             }   
  72.         ]]-->  
  73.     </mx:Script>  
  74.     <mx:Panel x="28.5" y="24" width="233" height="79" layout="absolute" title="登录窗口" visible="false">  
  75.         <mx:Label text="用户名" width="38" x="10" y="10"/>  
  76.         <mx:TextInput id="m_name_input" width="97" x="52" y="8"/>  
  77.     </mx:Panel>  
  78.     <mx:Panel x="28.5" y="40" width="331" height="312" layout="absolute" title="聊天测试">  
  79.         <mx:TextArea x="10" y="10" height="227" width="290" id="m_textarea" editable="false"/>  
  80.         <mx:TextInput x="10" y="245" width="233" id="m_text_input" enabled="false"/>  
  81.         <mx:Button x="253" y="245" label="发送" click="onSend()" enabled="false" id="send_btn"/>  
  82.     </mx:Panel>  
  83.     <mx:Button label="登录" id="loginbtn" click="onLogin()" x="122.5" y="10"/>  
  84.     <mx:TextInput x="66.5" y="10" width="48" id="m_port_input" text="1500"/>  
  85.     <mx:Button x="294" y="10" label="清屏" click="ClearScreen()"/>  
  86.     <mx:Label x="28.5" y="12" text="端口号"/>  
  87. </mx:Application>  

[xhtml]  view plain copy print ?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="388" height="376" applicationComplete="init()">  
  3.     <mx:Script>  
  4.         <!--[CDATA[  
  5.             import flash.net.Socket;  
  6.             import flash.utils.ByteArray;  
  7.             private var socket:Socket=new Socket();  
  8.               
  9.             private var strInfor:String = "";  
  10.             private var m_name:String = "";  
  11.             private var m_msg:String = "";  
  12.               
  13.             internal function init():void  
  14.             {  
  15.                 m_textarea.text = "";  
  16.             }  
  17.             internal function onLogin():void  
  18.             {  
  19.                 socket.connect("127.0.0.1",int(m_port_input.text));//执行连接  
  20.                 socket.addEventListener(Event.CONNECT,funConnect);  
  21.                 socket.addEventListener(Event.CLOSE,funClose);  
  22.                 socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);  
  23.             }  
  24.             internal function onSend():void  
  25.             {  
  26.                 m_msg = m_text_input.text;  
  27.                 socket.writeMultiByte(m_msg, "utf-8");  
  28.                 socket.flush();  
  29.             }  
  30.             internal function funConnect(event:Event):void  
  31.             {  
  32.                 funUpdateText("连接成功!");  
  33.                 m_text_input.enabled = true;  
  34.                 send_btn.enabled = true;  
  35.             }  
  36.             internal function funClose(event:Event):void  
  37.             {  
  38.                 funUpdateText("连接关闭!");  
  39.             }  
  40.             internal function funSocket(event:ProgressEvent):void  
  41.             {  
  42.                 var msg:String="";  
  43.                 while(socket.bytesAvailable)  
  44.                  {  
  45.                         msg+=socket.readMultiByte(socket.bytesAvailable,"utf8");  
  46.                         var arr:Array=msg.split('n');  
  47.                         for(var i:int=0;i<arr.length;i++)  
  48.                         {  
  49.                             if(arr[i].length>1)  
  50.                             {  
  51.                                 var myPattern:RegExp=/r/;  
  52.                                 arr[i]=arr[i].replace(myPattern,'');  
  53.                                 funUpdateText(arr[i]);  
  54.                             }  
  55.                         }  
  56.                 }  
  57.                 m_text_input.text = "";  
  58.             }  
  59.               
  60.             internal function funUpdateText(str:String):void  
  61.             {  
  62.                 strInfor += str + "/n";  
  63.                 m_textarea.text = strInfor;  
  64.                 m_textarea.verticalScrollPosition = m_textarea.maxVerticalScrollPosition;//滚动到最下面  
  65.             }  
  66.               
  67.             internal function ClearScreen():void  
  68.             {  
  69.                 strInfor = "";  
  70.                 m_textarea.text = "";  
  71.             }  
  72.         ]]-->  
  73.     </mx:Script>  
  74.     <mx:Panel x="28.5" y="24" width="233" height="79" layout="absolute" title="登录窗口" visible="false">  
  75.         <mx:Label text="用户名" width="38" x="10" y="10"/>  
  76.         <mx:TextInput id="m_name_input" width="97" x="52" y="8"/>  
  77.     </mx:Panel>  
  78.     <mx:Panel x="28.5" y="40" width="331" height="312" layout="absolute" title="聊天测试">  
  79.         <mx:TextArea x="10" y="10" height="227" width="290" id="m_textarea" editable="false"/>  
  80.         <mx:TextInput x="10" y="245" width="233" id="m_text_input" enabled="false"/>  
  81.         <mx:Button x="253" y="245" label="发送" click="onSend()" enabled="false" id="send_btn"/>  
  82.     </mx:Panel>  
  83.     <mx:Button label="登录" id="loginbtn" click="onLogin()" x="122.5" y="10"/>  
  84.     <mx:TextInput x="66.5" y="10" width="48" id="m_port_input" text="1500"/>  
  85.     <mx:Button x="294" y="10" label="清屏" click="ClearScreen()"/>  
  86.     <mx:Label x="28.5" y="12" text="端口号"/>  
  87. </mx:Application>  

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值