重明鸟软件知识平台
@网络编程:TCP
网络TCP和UDP连接过程大至一样,客户端必须知道服务端的IP地址和监听端口。而服务端必须监听指定端口。当有申请访问进来时,对进来数据进行分析,然后做出相应的处理。

我们创建两个基于TCP链接的程序,让他们进行最简单的信息发送。一个是CLIENT,一个是SERVER。他们一个扮演客户端角色,一个扮演服务端角色。我们还把TCP链接常用的函数和功能分别打包成两个类NClient和NServer,让这两个程序分别调用。

NCLient类源码:
/*
基于WIN32+codeblocks12.11平台下。
winsock2.h要写在windows.h上面
*/
#include<winsock2.h>
#include<windows.h>
//使用winsock库,CODEBLOCKS不需要下面这句,VC才要
//#pragma comment(lib,"ws2_32.lib")
   
class NClient
{
private:
    bool isTcp;
    SOCKET m_ClientSocket;
private:
// 检查是否支持2.0
    bool TestVersion()
    {
        WSADATA wsaData;
        WORD version = MAKEWORD(2,0);
        //初始化WinSock DLL库
        int ret = WSAStartup(version,&wsaData);
        if(ret!=0)
            return false;
        return true;
    }
public:
    void CleanClient()
    {
        closesocket(m_ClientSocket);
        WSACleanup();
    }
   
    bool InitTcpClient()
    {
        if(false==TestVersion())
            return false;
    //初始化socket为TCP模式
        m_ClientSocket = socket(AF_INET,SOCK_STREAM,0);
   
        if(m_ClientSocket == -1)
            return false;
   
        isTcp = true;
        return true;
    }
   
    bool ConnectTcp(const char* IP,int port)
    {
        SOCKADDR_IN m_addr;
        //使用INET协议族
        m_addr.sin_family = AF_INET;
        //设置要链接远程计算机的IP
        m_addr.sin_addr.S_un.S_addr = inet_addr(IP);
        //htons将主机字节变为网络字节
        m_addr.sin_port = htons(port);
        //链接远程计算机
        int ret = connect(m_ClientSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));
        if(ret == SOCKET_ERROR)
            return false;
        return true;
    }
   
    /*
    发送字符串给远程计算机,保证所以字符都能成功发送。
    */
    bool SendTcpMsg(const char* str)
    {
        int sendlen = 0;
        int len = strlen(str);
        while(len>0)
        {
            sendlen = send(m_ClientSocket,&(str[sendlen]),len,0);
            if(sendlen == SOCKET_ERROR)
            {
                closesocket(m_ClientSocket);
                return false;
            }
        len -= sendlen;
        }
        return true;
    }
   
    /*
    从远程计算机接收字符串,保证所以字符都能成功接送。
    */
    bool RecvTcpMsg(char* str,int len)
    {
        int recvlen = 0;
        int oldlen = len;
        while(len>0)
        {
            recvlen = recv(m_ClientSocket,&(str[recvlen]),len,0);
            if(recvlen == SOCKET_ERROR)
            {
                closesocket(m_ClientSocket);
                return false;
            }
            len -= recvlen;
        }
        //字符串终结符
        str[oldlen]="\n";
        return true;
   }
};


Client:源程序:

#include <stdio.h>
#include <conio.h>
#include "NClient.cpp"
int main()
{
    NClient* m_Client = new NClient();
    if(false == m_Client->InitTcpClient())
    {
        printf("Init TCP Client error!\n");
        return 0;
    }
   
    if(false==m_Client->ConnectTcp("192.168.1.101",10001))
    {
        printf("connect server error!\n");
        m_Client->CleanClient();
        return 0;
    }
   
    char msg[2];
    memset(msg,0,2);
   
    //向服务端发送两个字节“OK”,然后监听来自服务端信息,正确应该返回ok
    m_Client->SendTcpMsg("ok");
    m_Client->RecvTcpMsg(msg,2);
    printf("recv %s,len=%d",msg,strlen(msg));
    return 0;
}


NServer类源码:

/*
在UBUNTU平台
codeblocks12.11+GCC4.1编译对过
*/
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<stdio.h>
class NServer
{
private:
    int m_ServerSocket;
    int m_Port;
    int m_Len;
   
    char* r_msg;
public:
    NServer()
    {
        r_msg = NULL;
    }
   
    void SetCharLen(int len)
    {
       m_Len = len;
   
       if(r_msg!=NULL)
          delete r_msg;
   
       r_msg = new char[m_Len];
    }
    bool StartTcpServer(int port)
    {
    /*
     创建基于TCP的socket
    */
        m_ServerSocket = socket(AF_INET,SOCK_STREAM,0);
        if(m_ServerSocket == -1)
        {
            return false;
        }
        struct sockaddr_in m_addr;
   
        /*
         使用INET协议族,本机地址。并设置监听端口号。
        */
        m_addr.sin_family = AF_INET;
        m_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        m_addr.sin_port = htons(port);
        int addr_len = sizeof(m_addr);
   
       //绑定socket
        if(-1 == bind(m_ServerSocket,(struct sockaddr*)&m_addr,addr_len))
        {
            close(m_ServerSocket);
            return false;
        }
   
      //开始监听链接请求,16可以理解成同时监听链接数。
       listen(m_ServerSocket,16);
   
       while(true)
       {
           struct sockaddr_in client_address;
           unsigned int address_len = 0;
           int client_socket;
           address_len = sizeof(client_address);
   
           //接收链接请求,没有链接就一直在等待。
           client_socket = accept(m_ServerSocket,
                           (struct sockaddr *)(&client_address),&address_len);
   
          //输出请求链接的客户端IP地址
          printf("------------------\n");
          printf("client ip:%s",inet_ntoa(client_address.sin_addr));
          //接收客户端发来的信息。
          recv(client_socket,r_msg,2,0);
          r_msg[2]="\n";
          printf("recv msg:%s\n",r_msg);
         //将客户端发送来的信息回发回去。
          send(client_socket, r_msg,strlen(r_msg),0);
          close(client_socket);
          return true;
      }
      return true;
   }
};


Server源程序:
#include <iostream>
#include "NServer.cpp"
using namespace std;
int main()
{
    NServer* m_Server = new NServer;
    m_Server->SetCharLen(2);
    if(m_Server->StartTcpServer(10001)==false)
        cout << "Start TcpServer error!" << endl;
    return 0;
}
两个程序进行测试,先运行Server程序,再运行Client程序。 运行结果:
Server运行结果
———-
client ip:192.168.1.120
recv msg:ok

Client运行结果
recv msg:ok len=2
@站内查找
@栏目文章
【基础教程】Python守护进程创建
【基础教程】PyGame(13):三维环境设置
【基础教程】C/C++指针函数和回调函数
【基础教程】C/C++多进程编程(3)
【基础教程】C/C++多进程编程(2)
【基础教程】C/C++多进程编程(1)
【基础教程】C/C++多线程编程(2)
【基础教程】C/C++多线程编程(1)
【基础教程】C/C++动态库编程
【基础教程】C/C++静态库编程
【基础教程】photoshop图片混合公式
【基础教程】PyGame(12):旋转和缩放
【基础教程】PyGame(11):Surface操作
【基础教程】网络编程:Epoll(2)
【基础教程】网络编程:Epoll(1)
【基础教程】网络编程:IOCP(3)
【基础教程】网络编程:IOCP(2)
【基础教程】网络编程:IOCP(1)
【基础教程】网络编程:UDP
【基础教程】网络编程:TCP
【基础教程】Ubuntu安装Hadoop(4)
【基础教程】Ubuntu安装Hadoop(3)
【基础教程】Ubuntu安装Hadoop(2)
【基础教程】Ubuntu安装Hadoop(1)
【基础教程】Hadoop技术原理
【基础教程】Hadoop基本命令
【基础教程】Hadoop是什么东西
【基础教程】排序算法介绍
【基础教程】PyGame(10):声音控制
【基础教程】PyGame(9):鼠标事件(2)
【基础教程】PyGame(8):鼠标事件(1)
【基础教程】PyGame(7):键盘事件(2)
【基础教程】PyGame(6):键盘事件(1)
【基础教程】PyGame(5):显示图片
【基础教程】PyGame(4):显示文字
【基础教程】PyGame(3):图元绘制
【基础教程】PyGame(2):游戏框架
【基础教程】PyGame(1):开发环境搭建
【基础教程】Python(10):类定义
【基础教程】Python(9):自定义模块
【基础教程】Python(8):输入输出控制
【基础教程】Python(7):函数定义
【基础教程】Python(6):中断语句
【基础教程】Python(5):判断语句
【基础教程】Python(4):循环语句
【基础教程】Python(3):变量与运算符
【基础教程】Python(2):Hello
【基础教程】Python(1):介绍与安装
Copyright @ 2011-2018 by szc  桂ICP备11003301号-1  桂公网安备45040302000027号  Email:szcsoft@qq.com