精华内容
下载资源
问答
  • ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
    万次阅读 多人点赞
    2019-06-20 08:54:35

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

    共同学习成长QQ群 622368884,不喜勿加,里面有一大群志同道合的探路人

    快速导航
    单片机菜鸟的博客快速索引(快速找到你要的)

    如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。

    更多相关内容
  • c# TCPServer 源代码

    2020-10-11 23:30:20
    使用C#开发的 TCP SERVER 服务器,使用了多线程技术,从工作线程更新主线程的显示界面技术(委托) 使用C#开发的 TCP SERVER 服务器,使用了多线程技术,从工作线程更新主线程的显示界面技术(委托)
  • 一个简易的TCP服务器,用于测试连接。只能一对一进行传输
  • 基于delphi TCPclient与TCPserver的聊天程序 基于delphi TCPclient与TCPserver的聊天程序
  • Modbus TCP Server Tester

    2018-12-20 09:26:18
    标准Modbus TCP通信测试工具,两个测试工具主要用于plcModbus TCP通信测试,可分别可是客户端和服务器端 测试环境
  • TCPserver测试工具

    2018-08-04 09:34:27
    tcpserver,可以作为tcpclient测试工具。用于检测主机与TCP Server之间经过三次握手建立TCP连接的速度!
  • Go TCP Server库提供了tcpserver包来实现TCP服务器
  • TCP Server小程序,VS2013 C#完整工程,亲测可用。 学习中。。。
  • 模拟Modbus协议硬件,为工业物联网工业4.0提供编程学习方便。打开服务端软件后通过C#编程语言编写通信连接软件的客户端。通过改变对应地址的电位实现控制工控设备的功能。
  • HP-Socket开发TCP Server

    2018-03-27 13:32:32
    HP-Socket开发TCP Server。 简单地TCP Server,示例如何使用HP-Socket
  • MODBUS TCP SERVER 源码

    2017-08-01 16:09:22
    MODBUS TCP SERVER 源码,c++,实现了功能码 03,16。只是自己用于测试时开发的,功能有限,但可自行扩充。希望对您有用。
  • tcp_server - 一个Go库用于快速构建Tcp服务器
  • tcp server

    2015-11-18 15:36:57
    TCP 服务器端 能简单实现客户端和服务器端的通信,是一个入门级的小程序
  • C#编写的TCP异步通信,采用Socket实现,(还可用C#对Socket的封装TcpClient和TcpListener实现) 包含服务端及客户端完整代码
  • Poco:TCPServer框架

    2016-08-27 16:09:41
    poco的TCPServer框架,里面包含服务端和客户端代码,编译环境:VS2013 poco动态库:1.7.4完整版
  • TcpServer服务端测试

    2015-11-27 09:07:36
    测试利用socket进行tcp通信的工具,此工具为tcp socket通信服务器端!
  • TCP Server - TCP Client - VB源码 Form1是TCP Server端,Form2是TCP Client端,测试可用,源码已生成EXE。
  • ModbusTcpServer

    2015-07-21 09:25:14
    实现了工业标准ModbusTcp协议的Demo例子,目前只实现了03号命令,底层使用SuperSocket实现通讯,例子简单明了,注释清晰,写这个Demo用了大概用了两个小时的时间,如有问题请多指教。
  • android TCP serverTCP client通信源码

    热门讨论 2012-05-04 12:44:32
    android TCP serverTCP client通信源码 手机成功与串口WIFI模块ST-MW-08S通信。
  • 使用C++ 实现TCP server

    千次阅读 2022-03-29 09:34:06
    相关函数3.1 subcallback3.2 server与client的交互函数3.3 循环向所有连接发送信息的函数总结 前言 工作内容:为每个连接建立线程进行交互,并单独使用一个线程向所有连接持续发送相同数据.主线程执行等待连接. ...


    前言

    工作内容:为每个连接建立线程进行交互,并单独使用一个线程向所有连接持续发送相同数据.主线程执行等待连接. 本实现在ros下,使用C++语言和如下头文件所示的相关库.


    1.头文件

    #include <arpa/inet.h>  
    #include <netinet/in.h>
    #include <ros/ros.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <cerrno>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <string>
    #include  <pthread.h>
    
    #include<signal.h>
    
    #define SERV_PORT 8888
    #define LISTEN_COUNT 5
     
    ros::Publisher* m_pub;
    pthread_mutex_t cm_mutex;
    struct connect_message{
        int connfd;
        struct sockaddr_in cliaddr;
    };
    std::vector<connect_message> all_connect;
    

    2.main函数

    代码如下(示例):

    
    int main(int argc, char** argv) {
        // create ros node
        ros::init(argc, argv, "my_server");
        ros::NodeHandle n;
        ros::Subscriber server_sub;
        server_sub = n.subscribe("sub", 1, subcallback);
        ros::Publisher pub = n.advertise<std_msgs::String>("pub", 1);
        m_pub = &pub;
        ros::Rate loop_rate(1); 
        signal(SIGINT, mySigintHandler);//放到NodeHandle 和 Rate 后面
    
        std::cout << "start server" << std::endl;
    
        struct sockaddr_in cliaddr;
        socklen_t cliaddr_len;
        int connfd;
    
        // socket   init
        int listenfd = socket(AF_INET, SOCK_STREAM, 0);
        if (listenfd == -1) {
            std::cout << "Error  socket" << std::endl;
            return 0;
        }
        // bind   port
        struct sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_port = htons(SERV_PORT);
        addr.sin_addr.s_addr = INADDR_ANY;
        int opt = 1;
        setsockopt(listenfd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
        if (bind(listenfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
            std::cout << "Error bind" << std::endl;
            return 0;
        }
    
        // listener
        if (listen(listenfd, LISTEN_COUNT) == -1) {
            std::cout << "Error listen" << std::endl;
            return 0;
        }
    
        //add send thread
        pthread_mutex_init(&cm_mutex, NULL);
        pthread_t circular_trans_th;
        pthread_create(&circular_trans_th, NULL, circular_trans, (void*)&all_connect);
        pthread_detach(circular_trans_th);
    
        while (true) {
            cliaddr_len = sizeof(cliaddr);
            connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddr_len);
            // std::cout << "Device connection" << std::endl; 
            //添加数据到all_connect要使用锁
            {
             connect_message cm;
             cm.connfd = connfd;
             cm.cliaddr = cliaddr;
             pthread_mutex_lock(&cm_mutex);
             all_connect.push_back(cm);
             pthread_mutex_unlock(&cm_mutex);
            }
    
            char sendbuf[20] = {'\0'};
            ROS_INFO("connected : %s:%d\r\n", inet_ntop(AF_INET, (void*)&cliaddr.sin_addr, sendbuf, 16), cliaddr.sin_port);
     		//为每个连接开辟线程并分离
            pthread_t th;
            pthread_create(&th, NULL, msgRecv, (void*)&connfd);
            pthread_detach(th);  
            ros::spinOnce();
            loop_rate.sleep();
        }
    
        std::cout << "Socket close" << std::endl;
        close(listenfd);//接受后关闭
        return 0;
    }
    

    3.相关函数

    3.1 subcallback

    ros消息回调函数,其他实现请忽略.

    
    void subcallback(iau_ros_msgs::VehicleHmiConstPtr msg) {
          //数据处理
    }
    
      //该函数用于解决ros节点按ctrl+c不能终止的问题 #include<signal.h>
    void mySigintHandler(int sig){
        ROS_INFO("shutting down");
        ros::shutdown();
        exit(0);
    }
    

    3.2 server与client的交互函数

    void* msgRecv(void* arg){
        std_msgs::String msg;
        int newsock=*(int*)arg;
        char buf[1024];
        while (true){
            int len = recv(newsock, buf, sizeof(buf), 0);
            if(len>0){  
                 buf[len] = 0x00;
                 std::string s = buf;
                 std::cout << s << std::endl;  
                 msg.data=buf;
            m_pub->publish(msg);
            }
            else{//通过数据发送失败识别客户端断开连接,结束对应线程
                // std::cout << "Thread end\n";
                pthread_exit(NULL);  //线程退出
            }
        }
    }
    
    

    3.3 循环向所有连接发送信息的函数

     void* circular_trans(void* msg) {
         while (true) {
             while(all_connect.empty()) {
                 std::cout << "sleep3sec\n";
                 sleep(3);
             }
             pthread_mutex_lock(&cm_mutex);
             for (std::vector<connect_message>::iterator it = all_connect.begin(); it != all_connect.end(); ++it) {
             //构造数据
                 std::string str = "hello world";
                 int len = send(it->connfd, str.c_str(), str.size(), 0);
                 if (len < 0) {
                     //数据发送失败的时候,连接已经断开,应该马上跳出for重新读取all_connect,否则下一次循环还会识别到被删掉的数据,造成越界访问错误,应该是多线程造成的
                     close(it->connfd);  
                    char sendbuf[20] = {'\0'};
                     ROS_INFO("Disconnected : %s:%d\r\n", inet_ntop(AF_INET, (void*)&it->cliaddr.sin_addr, sendbuf, 16), it->cliaddr.sin_port);
                     all_connect.erase(it); 
                     break;
                 }
                 if (it == all_connect.end() - 1) { 
                     break;
                 }
             }
             pthread_mutex_unlock(&cm_mutex);
            //  sleep(1);  
         }
    }
    

    总结

    1.多线程的使用需要小心,detach的线程执行结束应该主动关闭.
    2.在数据上锁后数据更新需要重新上锁才能完成.
    3.accept写在死循环中可以持续监听连接.

    展开全文
  • 简单的Tcp server小程序

    2017-04-01 20:09:08
    简单的Tcp server小程序
  • 基于libevent的tcp server开发环境的完整工程
  • bas为boost_asio_server(baserver)的简称,是采用Half-Sync/Half-Async模式的服务器框架,使用c++实现,能够大大简化tcp server的开发工作。bas目前实现了以下功能: 1、底层基于boost及asio实现,支持ssl,跨越...
  • STM32+FreeRTOS+LWIP TCP Server多端口并发通信实例1. 问题的提出2. 设计思路3. 代码实现 1. 问题的提出 在LWIP的TCP Server功能的应用中,如何创建多个TCP服务器端口同时与多台客户端设备通信,或者如何在同一个TCP...

    STM32+FreeRTOS+LWIP TCP Server多端口并发通信实例

    1. 问题的提出

    在LWIP的TCP Server功能的应用中,如何创建多个TCP服务器端口同时与多台客户端设备通信,或者如何在同一个TCP服务器端口下创建多个连接同时与多台客户端通信?

    2. 设计思路

    • 利用FreeRTOS的多任务调度机制,一个任务对应一个服务器端口,实现多端口并发通信。
    • 如果在同一个端口下收到多个客户端连接请求,就利用FreeRTOS的消息队列,把新的连接分配到其他的任务中。

    3. 代码实现

    本例程使用lwip的netconn结构来实现tcp server的功能,通过dhcp获取ip地址,再创建两个port,5001和5002,其中5001端口可以连接2个tcp client。也就是说,本例程实现了多个端口连接不同设备和单个端口连接多个设备的功能。

    	ip address <--------->	netconn(5001) <-----> client1
    			 		|						 |--> client2
    					|
    					|---->	netconn(5002) <-----> client3
    

    5002端口的任务函数

    static void tcp_server_task(void* pvParameters)
    {
    	char tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];		//接收缓存区
    	char tcp_server_sendbuf[] = "tcp server msg\r\n";	//发送缓存区
    	unsigned int data_len = 0;
    	struct pbuf *q;
    	err_t err, recv_err;
    	unsigned char remote_addr[4];
    	struct netconn *conn, *newconn;
    	struct netbuf *recvbuf;
    	static ip_addr_t ipaddr;
    	static u16_t port;
    	
    	LWIP_UNUSED_ARG(pvParameters);
    	
    	conn = netconn_new(NETCONN_TCP);		//创建一个新的连接
    	netconn_bind(conn, IP_ADDR_ANY, 5002);	//绑定IP和端口
    	netconn_listen(conn);					//开始监听conn
    	netconn_set_recvtimeout(conn, 200);		//设置conn的接收超时
    	
    	while(1)
    	{
    		err = netconn_accept(conn, &newconn);	//在正在监听的连接conn上面接收新的连接newconn
    												//这个函数本身是有等待超时的特性
    		netconn_set_recvtimeout(newconn, 200);	//设置newconn的接收超时
    		
    		if(err == ERR_OK)	//如果newconn建立成功
    		{
    			netconn_getaddr(newconn, &ipaddr, &port, 0);
    			remote_addr[3] = (u8_t)(ipaddr.addr >> 24);
    			remote_addr[2] = (u8_t)(ipaddr.addr >> 16);
    			remote_addr[1] = (u8_t)(ipaddr.addr >> 8);
    			remote_addr[0] = (u8_t)(ipaddr.addr);
    			printf("Dest IP: %d.%d.%d.%d  Port: %d\r\n", remote_addr[0],\
    					remote_addr[1], remote_addr[2], remote_addr[3], port);
    			
    			while(1)
    			{
    				if(1)	//这里可以添加发送数据的标记位
    				{
    					err = netconn_write(newconn, tcp_server_sendbuf, \
    							strlen(tcp_server_sendbuf), NETCONN_NOFLAG);
    					if(err != ERR_OK)
    						printf("tcp server send failed\r\n");
    				}
    				
    				//接收newconn的数据,有等待超时
    				if((recv_err = netconn_recv(newconn, &recvbuf)) == ERR_OK)
    				{
    					taskENTER_CRITICAL();//进入临界段
    					memset(tcp_server_recvbuf, 0, TCP_SERVER_RX_BUFSIZE);
    					for(q=recvbuf->p; q!=NULL; q=q->next)
    					{
    						if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len))
    						{
    							memcpy(tcp_server_recvbuf+data_len, q->payload, \
    									TCP_SERVER_RX_BUFSIZE-data_len);
    						}
    						else
    						{
    							memcpy(tcp_server_recvbuf+data_len, q->payload, q->len);
    						}
    						
    						data_len += q->len;
    						
    						if(data_len > TCP_SERVER_RX_BUFSIZE)
    							break;
    					}
    					taskEXIT_CRITICAL();//退出临界段
    					data_len = 0;
    					printf("%s", tcp_server_recvbuf);
    					netbuf_delete(recvbuf);
    				}
    				//检测到newconn连接关闭,则断开
    				else if(recv_err == ERR_CLSD)
    				{
    					netconn_close(newconn);
    					netconn_delete(newconn);
    					printf("tcp server disconnected\r\n");
    					break;
    				}
    			}
    		}
    	}
    }
    

    5001端口分配连接的任务。收到连接请求就把新的netconn发送出去。

    static void tcp_conn_distrib_task(void *pvParameters)
    {
    	struct netconn *conn = NULL;
    	struct netconn *newconn = NULL;
    	err_t err;
    	
    	conn = netconn_new(NETCONN_TCP);		//创建连接
    	netconn_bind(conn, IP_ADDR_ANY, 5001);	//绑定IP和端口
    	netconn_listen(conn);					//监听conn
    	netconn_set_recvtimeout(conn, 200);		//设置conn超时时间
    	
    	while(1)
    	{
    		err = netconn_accept(conn, &newconn);	//接收newconn
    		netconn_set_recvtimeout(newconn, 200);	//设置newconn的超时时间
    		
    		if(err == ERR_OK && newconn != last_newconn)
    		{
    			printf("queue send\r\n");
    			xQueueSend(tcp_conn_distrib, &newconn, 0);	//检测到有新的连接就分配
    		}
    	}
    }
    

    5001端口的第一个netconn

    static void tcp_conn_first_task(void *pvParameters)
    {
    	char tcp_server_sendbuf[] = "first tcp con msg\r\n";
    	char tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];
    	err_t err, recv_err;
    	struct netconn *first_conn;
    	struct netbuf *recvbuf;
    	struct pbuf *q;
    	unsigned int data_len = 0;
    	static ip_addr_t ipaddr;
    	static u16_t port;
    	unsigned char remote_addr[4];
    	
    	while(1)
    	{
    		//等待分配连接的消息队列,阻塞
    		xQueueReceive(tcp_conn_distrib, &first_conn, portMAX_DELAY);
    		
    		netconn_getaddr(first_conn, &ipaddr, &port, 0);
    		remote_addr[3] = (u8_t)(ipaddr.addr >> 24);
    		remote_addr[2] = (u8_t)(ipaddr.addr >> 16);
    		remote_addr[1] = (u8_t)(ipaddr.addr >> 8);
    		remote_addr[0] = (u8_t)(ipaddr.addr);
    		printf("Dest IP: %d.%d.%d.%d  Port: %d\r\n", remote_addr[0], \
    				remote_addr[1], remote_addr[2], remote_addr[3], port);
    		
    		while(1)
    		{
    			if(1)	//这里可以添加发送数据的标记位
    			{
    				err = netconn_write(first_conn, tcp_server_sendbuf, \
    							strlen(tcp_server_sendbuf), NETCONN_NOFLAG);
    				if(err != ERR_OK)
    					printf("first conn send failed\r\n");
    			}
    			
    			if((recv_err = netconn_recv(first_conn, &recvbuf)) == ERR_OK)
    			{
    				taskENTER_CRITICAL();//进入临界段
    				memset(tcp_server_recvbuf, 0, TCP_SERVER_RX_BUFSIZE);
    				for(q=recvbuf->p; q!=NULL; q=q->next)
    				{
    					if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len))
    					{
    						memcpy(tcp_server_recvbuf+data_len, q->payload, \
    								TCP_SERVER_RX_BUFSIZE-data_len);
    					}
    					else
    					{
    						memcpy(tcp_server_recvbuf+data_len, q->payload, q->len);
    					}
    					
    					data_len += q->len;
    					
    					if(data_len > TCP_SERVER_RX_BUFSIZE)
    						break;
    				}
    				taskEXIT_CRITICAL();//退出临界段
    				data_len = 0;
    				printf("%s", tcp_server_recvbuf);
    				netbuf_delete(recvbuf);
    			}
    			else if(recv_err == ERR_CLSD)
    			{
    				netconn_close(first_conn);
    				netconn_delete(first_conn);
    				printf("first conn disconnected\r\n");
    				break;
    			}
    		}
    	}
    }
    

    5001端口的第二个netconn,代码和上一个任务基本是一样的

    static void tcp_conn_second_task(void *pvParameters)
    {
    	err_t err, recv_err;
    	struct netconn *second_conn;
    	struct netbuf *recvbuf;
    	struct pbuf *q;
    	unsigned int data_len = 0;
    	static ip_addr_t ipaddr;
    	static u16_t port;
    	unsigned char remote_addr[4];
    	char tcp_server_sendbuf[] = "second tcp con msg\r\n";
    	char tcp_server_recvbuf[TCP_SERVER_RX_BUFSIZE];
    	
    	while(1)
    	{
    		//等待分配连接的消息队列,阻塞
    		xQueueReceive(tcp_conn_distrib, &second_conn, portMAX_DELAY);
    		
    		netconn_getaddr(second_conn, &ipaddr, &port, 0);
    		remote_addr[3] = (u8_t)(ipaddr.addr >> 24);
    		remote_addr[2] = (u8_t)(ipaddr.addr >> 16);
    		remote_addr[1] = (u8_t)(ipaddr.addr >> 8);
    		remote_addr[0] = (u8_t)(ipaddr.addr);
    		printf("Dest IP: %d.%d.%d.%d  Port: %d\r\n", remote_addr[0], \
    				remote_addr[1], remote_addr[2], remote_addr[3], port);
    		
    		while(1)
    		{
    			if(1)	//这里可以添加发送数据的标记位
    			{
    				err = netconn_write(second_conn, tcp_server_sendbuf, \
    							strlen(tcp_server_sendbuf), NETCONN_NOFLAG);
    				if(err != ERR_OK)
    						printf("second conn send failed\r\n");
    			}
    			
    			if((recv_err = netconn_recv(second_conn, &recvbuf)) == ERR_OK)
    			{
    				taskENTER_CRITICAL();//进入临界段
    				memset(tcp_server_recvbuf, 0, TCP_SERVER_RX_BUFSIZE);
    				for(q=recvbuf->p; q!=NULL; q=q->next)
    				{
    					if(q->len > (TCP_SERVER_RX_BUFSIZE-data_len))
    					{
    						memcpy(tcp_server_recvbuf+data_len, q->payload, \
    								TCP_SERVER_RX_BUFSIZE-data_len);
    					}
    					else
    					{
    						memcpy(tcp_server_recvbuf+data_len, q->payload, q->len);
    					}
    					
    					data_len += q->len;
    					
    					if(data_len > TCP_SERVER_RX_BUFSIZE)
    						break;
    				}
    				taskEXIT_CRITICAL();//退出临界段
    				data_len = 0;
    				printf("%s", tcp_server_recvbuf);
    				netbuf_delete(recvbuf);
    			}
    			else if(recv_err == ERR_CLSD)
    			{
    				netconn_close(second_conn);
    				netconn_delete(second_conn);
    				printf("second conn disconnected\r\n");
    				break;
    			}
    		}
    	}
    }
    

    4. 参考

    • 野火电子《LwIP 应用开发实战指南》第15章 使用NETCONN变成
    • 正点原子《STM32F4 LWIP开发手册V3.0》第十章 NETCONN 编程接口 TCP 服务器实验
    展开全文
  • 使用TCPServer编写(多线程)socket服务 http://blog.csdn.net/ghostfromheaven/article/details/8653421
  • ESP32 开发之旅⑨ TCP Server

    千次阅读 2020-01-08 23:20:59
    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥... WiFiServer库2.1 管理server2.1.1 WiFiServer server(port) —...

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力。希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石。。。

    快速导航
    单片机菜鸟的博客快速索引(快速找到你要的)

    如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。

    展开全文
  • JAVA实现TCPServer和TCPClient

    千次阅读 2020-05-09 12:15:26
    JAVA实现TCP服务端和客户端。
  • Rust Web 全栈开发 - 1 构建TCP Server

    千次阅读 2022-03-27 23:11:33
    1. 构建TCP Server 具体来说就是要编写一个TCP Server 和 Client,然后让他们通信 先创建一个文件夹并打开 cargo new s1 && cd s1 再创建两个文件夹 cargo new tcpserver ...members = ["tcpserver",
  • muduo之TcpServer

    万次阅读 2019-10-10 21:00:05
    TcpServer拥有Acceptor类,新连接到达时new TcpConnection后续客户端和TcpConnection类交互。TcpServer管理连接和启动线程池,用Acceptor接受连接。 // Copyright 2010, Shuo Chen. All rights reserved. // ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 777,172
精华内容 310,868
关键字:

TCP server

友情链接: AN010_CN.zip