整理socket编程<一>:win32 socket简易服务器开发
来源:互联网 发布:转录组数据上传 编辑:程序博客网 时间:2024/05/12 01:39
1.功能
windows下实现socket的简易服务器开发,接收来自于客户端的连接和业务请求,并给出响应。
2.原理
当然在进行socket编程时,要首先初始化socket环境
//初始化winsock环境WSAData wsa_data;WORD ver =MAKEWORD(2, 2);if(WSAStartup(ver, &wsa_data) != 0){std::cout << "初始化winsock环境失败" << std::endl;return -1;}
对应的清理socket环境
WSACleanup();
3.服务器实现
实现一个同步服务器,通过winsock2和ws2_32.lib,利用boost::threadgroup(线程池)实现较为高效的处理,阻塞模式,主线程负责接收客户端的连接请求,子线程负责socket业务通信
#include "stdafx.h"#include <WinSock2.h>#include <iostream>#include <MSTCPiP.h>//#define BOOST_ALL_DYN_LINK//使用动态库链接#include <boost/thread.hpp>#include <boost/bind.hpp>#include <boost/asio.hpp>#include <boost/smart_ptr.hpp>#pragma comment(lib,"WS2_32.lib")void handle_msg(SOCKET con_socket){if (con_socket == INVALID_SOCKET){return;}char server_text[] = "TCP server demo!";char szMessage[1024] = {0};while(true){int ret_size = recv(con_socket, szMessage, 1024, 0);if ( (ret_size == 0) || (ret_size == SOCKET_ERROR) ){printf("Client has closed the connection\n"); return;}else{szMessage[ret_size] = '\0';std::cout << boost::this_thread::get_id() << "接收到数据:" << szMessage <<std::endl;}send(con_socket, server_text, strlen(server_text), 0);}}//同步服务器,利用winsock2和ws2_32.lib,利用boost::threadgroup(线程池)实现较为高效的处理,阻塞模式,主线程负责接收客户端的连接请求,子线程负责socket业务通信int SyncSocketSvr() {WSADATA wsaData;//初始化socket环境if(WSAStartup(0x0202, &wsaData) != 0){std::cout << "初始化socket lib环境失败" << std::endl;return -1;}//创建socketSOCKET listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (listen_sock == INVALID_SOCKET){std::cout << "创建socket失败" << std::endl;return -1;}//初始化服务器的IP地址sockaddr_in server_addr;memset(&server_addr, 0, sizeof(sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY);server_addr.sin_port = htons(2000);//绑定IP到socket上if(bind(listen_sock, (LPSOCKADDR)&server_addr, sizeof(server_addr)) == SOCKET_ERROR){std::cout << "bind failed!" << std::endl;return -1;}//开启监听if (listen(listen_sock, 3) == SOCKET_ERROR){std::cout << "listen failed" << std::endl;}//循环接收客户端的连接请求sockaddr_in remote_addr;memset(&remote_addr, 0, sizeof(sockaddr_in));int addr_len = sizeof(sockaddr_in);SOCKET connect_sock;char server_text[] = "TCP server demo!";boost::thread_group tg;while(true){connect_sock = accept(listen_sock, (LPSOCKADDR)&remote_addr, &addr_len);if (connect_sock == INVALID_SOCKET){std::cout << "connect failed!" << std::endl;return -1;}std::cout << "接收到一个连接请求,IP:" << inet_ntoa(remote_addr.sin_addr) << std::endl;//主流做法:创建一个子线程,绑定这个socket,负责此socket上的所有通信,或者采用线程池tg.create_thread(boost::bind(handle_msg, connect_sock));}tg.join_all();//关闭连接closesocket(listen_sock);WSACleanup();return 0;}
4.简易客户端实现
#include "stdafx.h"#include <winsock2.h>#include <iostream>#pragma comment(lib, "WS2_32.lib")int _tmain(int argc, _TCHAR* argv[]){//初始化winsock环境WSAData wsa_data;WORD ver =MAKEWORD(2, 2);if(WSAStartup(ver, &wsa_data) != 0){std::cout << "初始化winsock环境失败" << std::endl;return -1;}//创建socketSOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (client_socket == INVALID_SOCKET){std::cout << "创建socket失败" << std::endl;return -1;}//远程服务器信息sockaddr_in server_addr;memset(&server_addr, 0, sizeof(sockaddr_in));server_addr.sin_family = AF_INET;server_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");server_addr.sin_port = htons(2000);//连接远程服务器int ret = connect(client_socket, (sockaddr *)&server_addr, sizeof(server_addr));if (ret == SOCKET_ERROR){std::cout << "连接远程服务器失败" << std::endl;return -1;}const int MESSAGE_SIZE = 1024;char szMessage[MESSAGE_SIZE] = {0};while (true){int receive_ret = recv(client_socket, szMessage, MESSAGE_SIZE, 0);std::cout << "收取到[" << receive_ret << "]字节:" << szMessage << std::endl;std::cout << "send::" << std::endl;gets_s(szMessage);size_t message_len = strlen(szMessage);int send_ret = send(client_socket, szMessage, message_len, 0);if (send_ret != message_len){std::cout << "发送数据失败" << std::endl;return -1;}}closesocket(client_socket);WSACleanup();return 0;}客户端实现比较简单,连接的是本地的服务器。
5.总结
上面是我自己实现的一个简单的TCP服务器和客户端的demo,不过里面使用了现在主流的同步服务器的实现机制,即连接和业务分离,当处理大量的并发连接时,需要使用I/O复用模型,同时监听多个I/O端口,可以参考下某位大牛的这篇文章:http://blog.csdn.net/hguisu/article/details/7453390
1 0
- 整理socket编程<一>:win32 socket简易服务器开发
- 【Socket编程】Python实现简易Web服务器
- 服务器开发【一】----网络编程的基础SOCKET(1)
- Java Socket编程与客户/服务器应用开发(一)
- win32 socket编程帮助
- WIN32 socket编程
- Win32 Socket编程注意事项
- Socket 连接简易编程
- Socket编程(简易聊天室客户端/服务器编写、CocoaAsyncSocket)
- Socket编程 简易测试socket TCP程序
- Socket编程 简易测试socket UDP
- Socket编程一实现简易的聊天功能以及文件传输
- Socket编程一实现简易的聊天功能以及文件传输
- socket编程整理
- win32下Socket编程(1)
- win32下Socket编程(1)
- win32 socket编程帮助(二)
- win32下C++ Socket编程
- 如何区分InputStream和OutputStream
- Convert.ToInt16(s);int.Parse(s);和(int)s的区别
- PL/SQL连接Linux服务器Oracle遇到的问题总结
- 【BLE】CC2541之自定义按键
- java 网络 socket TCP / UDP / catch 语句块捕捉到异常后,继续执行语句块后面的代码
- 整理socket编程<一>:win32 socket简易服务器开发
- beaglebone 损坏!
- JavaScript中的prototype(原型)相关问题
- 使用MapReduce实现专利文件的分析
- linux命令别名与常用快捷键-52
- 路由映射外网
- c#简单的序列化和反序列化
- 多维数组
- JQuery删除cookie失效