jianplx 发表于 2014-10-11 12:41:07

寻找一个能转发的TCP服务器程序

设备1和设备2都能通过网络(外网)连接这个TCP服务器程序,然后这个服务器能把设备1的数据转发给设备2,同样设备2的数据转发给设备1,有没有这样功能的程序工具吖

jianplx 发表于 2014-10-11 12:43:29

我这里有一个固定的IP地址 IP: 123.157.xxx.xxx浙江省金华市 联通 想用来当服务器转发有些数据

lubing521 发表于 2014-10-11 12:57:16

自己开发一个呗。或者你可以看看turnserver

jxcylxh 发表于 2014-10-11 13:03:47

Linux还是哪里,Linux的我在网上找了一个:/*************************************************
* File name   : server.c
* Description : 单进程并发服务器
* Author      : sg131971@qq.com
* Version   : V1.0
* Date      :
* Compiler    : arm-linux-gcc-4.4.3
* Target      : mini2440(Linux-2.6.32)
* History   :
*   <author><time>   <version >   <desc>
*************************************************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <stdlib.h>

#define PORT 1234               //服务器端口
#define BACKLOG 5               //listen队列中等待的连接数
#define MAXDATASIZE 1024      //缓冲区大小

typedef struct _CLIENT
{
    int fd;                     //客户端socket描述符
    char name;            //客户端名称
    struct sockaddr_in addr;    //客户端地址信息结构体
    char data;   //客户端私有数据指针
} CLIENT;

void process_client(CLIENT * client, char *recvbuf, int len);   //客户请求处理函数

/*************************************************
* Function    : main()
* Description :
* Calls       : process_client()
* Called By   :
* Input       :
* Output      :
* Return      :
*************************************************/
void main(int argc ,char **argv)
{
    int i, maxi, maxfd, sockfd;
    int nready;
    ssize_t n;
    fd_set rset, allset;      //select所需的文件描述符集合
    int listenfd, connectfd;    //socket文件描述符
    struct sockaddr_in server;//服务器地址信息结构体

    CLIENT client;//FD_SETSIZE为select函数支持的最大描述符个数
    char recvbuf;//缓冲区
    int sin_size;               //地址信息结构体大小

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {                           //调用socket创建用于监听客户端的socket
      perror("Creating socket failed.");
      exit(1);
    }

    int opt = SO_REUSEADDR;
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));//设置socket属性

    bzero(&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1)
    {                           //调用bind绑定地址
      perror("Bind error.");
      exit(1);
    }

    if (listen(listenfd, BACKLOG) == -1)
    {                           //调用listen开始监听
      perror("listen() error\n");
      exit(1);
    }

    //初始化select
    maxfd = listenfd;
    maxi = -1;
    for (i = 0; i < FD_SETSIZE; i++)
    {
      client.fd = -1;
    }
    FD_ZERO(&allset);         //清空
    FD_SET(listenfd, &allset);//将监听socket加入select检测的描述符集合

    while (1)
    {
      struct sockaddr_in addr;
      rset = allset;
      nready = select(maxfd + 1, &rset, NULL, NULL, NULL);    //调用select
      //printf("Select() break and the return num is %d. \n", nready);

      if (FD_ISSET(listenfd, &rset))
      {                     //检测是否有新客户端请求
            printf("Accept a connection.\n");
            //调用accept,返回服务器与客户端连接的socket描述符
            sin_size = sizeof(struct sockaddr_in);
            if ((connectfd =
               accept(listenfd, (struct sockaddr *)&addr, (socklen_t *) & sin_size)) == -1)
            {
                perror("Accept() error\n");
                continue;
            }

            //将新客户端的加入数组
            for (i = 0; i < FD_SETSIZE; i++)
            {
                if (client.fd < 0)
                {
                  char buffer;
                  client.fd = connectfd;   //保存客户端描述符
                  memset(buffer, '0', sizeof(buffer));
                  sprintf(buffer, "Client[%.2d]", i);
                  memcpy(client.name, buffer, strlen(buffer));
                  client.addr = addr;
                  memset(buffer, '0', sizeof(buffer));
                  sprintf(buffer, "Only For Test!");
                  memcpy(client.data, buffer, strlen(buffer));
                  printf("You got a connection from %s:%d.\n", inet_ntoa(client.addr.sin_addr),ntohs(client.addr.sin_port));
                  printf("Add a new connection:%s\n",client.name);
                  break;
                }
            }
            
            if (i == FD_SETSIZE)
                printf("Too many clients\n");
            FD_SET(connectfd, &allset); //将新socket连接放入select监听集合
            if (connectfd > maxfd)
                maxfd = connectfd;//确认maxfd是最大描述符
            if (i > maxi)       //数组最大元素值
                maxi = i;
            if (--nready <= 0)
                continue;       //如果没有新客户端连接,继续循环
      }

      for (i = 0; i <= maxi; i++)
      {
            if ((sockfd = client.fd) < 0)    //如果客户端描述符小于0,则没有客户端连接,检测下一个
                continue;
            // 有客户连接,检测是否有数据
            if (FD_ISSET(sockfd, &rset))
            {
            //printf("Receive from connect fd[%d].\n", i);
                if ((n = recv(sockfd, recvbuf, MAXDATASIZE, 0)) == 0)
                {               //从客户端socket读数据,等于0表示网络中断
                  close(sockfd);//关闭socket连接
                  printf("%s closed. User's data: %s\n", client.name, client.data);
                  FD_CLR(sockfd, &allset);    //从监听集合中删除此socket连接
                  client.fd = -1;//数组元素设初始值,表示没客户端连接
                }
                else
                                {
                               
                                }
                   // process_client(&client, recvbuf, n); //接收到客户数据,开始处理
                if (--nready <= 0)
                  break;      //如果没有新客户端有数据,跳出for循环回到while循环
            }
      }
    }
    close(listenfd);            //关闭服务器监听socket   
}

/*************************************************
* Function    : process_client()
* Description : 处理客户端连接函数
* Calls       :
* Called By   : main()
* Input       :
* Output      :
* Return      :
*************************************************/
void process_client(CLIENT * client, char *recvbuf, int len)
{
    char sendbuf;
    int i;

//printf("Received client( %s ) message: %s\n", client->name, recvbuf);
   
    for (i = 0; i < len - 1; i++)
    {
      sendbuf = recvbuf;
    }
   
    sendbuf = '\0';

    send(client->fd, sendbuf, strlen(sendbuf), 0);
}

jxcylxh 发表于 2014-10-11 13:08:02

简单改一下就可以用了。

liuruoshui 发表于 2014-10-12 08:19:28

标记学习

GunGun 发表于 2014-10-12 08:31:15

这个很简单吧。

youkebing 发表于 2014-10-12 08:39:58

自已开发一个吧,不复杂。

youkebing 发表于 2014-10-12 08:41:43

还有,在协议上圹充点会更好

jianplx 发表于 2014-10-13 08:18:47

学习了 谢谢吖

wdluo 发表于 2014-11-4 20:58:09

yeelink不就是实现这样的功能?

jianplx 发表于 2014-11-6 09:27:14

wdluo 发表于 2014-11-4 20:58
yeelink不就是实现这样的功能?

我刚好有个固定地址,想用自己的服务器

longjane 发表于 2015-1-22 17:33:17

jianplx 发表于 2014-11-6 09:27
我刚好有个固定地址,想用自己的服务器

fuhome有设备转设备的API,不过是UDP,自己验证就没事,现在UDP也基本不会掉包了。
页: [1]
查看完整版本: 寻找一个能转发的TCP服务器程序