vc简易网络服务器、客户端实现
来源:互联网 发布:琪琪看片 mac版下载 编辑:程序博客网 时间:2024/06/05 19:16
一、服务器部分代码
头文件:server.h
源文件:server.cpp
2、客户端代码
头文件:client.h
源文件:client.cpp
头文件:server.h
- #include <winsock2.h>
- #include <stdio.h>
- #include <windef.h>
- #ifndef TCP_SERVER_H
- #define TCP_SERVER_H
- #pragma warning(disable : 4996)
- #define MAX_CLIENT (100)
- #define LISTEN_PORT (60000)
- #define CLIENT_TIMEOUT (15 * 60 * 60) /*客户端中断15分钟则服务器自动掉线*/
- #define MAX_TCP_PACKET_SIZE (1492)/*tcp最大数据包字节数*/
- typedef struct __client_item
- {
- SOCKET client;
- sockaddr_in form;
- unsigned int id;
- DWORD dwThreadId;
- HANDLE hThread;
- }_client_item;
- typedef struct __client_list
- {
- DWORD client_cnt;
- _client_item client_item[MAX_CLIENT];
- }_client_list;
- DWORD WINAPI serve_client_thread_func( LPVOID param_ptr );
- #endif/*TCP_SERVER_H*/
源文件:server.cpp
- #include "server.h"
- #include <sys\stat.h>
- #include <time.h>
- _client_list client_list;
- CRITICAL_SECTION cs_serve_main;
- CRITICAL_SECTION cs_serve_thread;
- _client_list *get_client_list(void)
- {
- return &client_list;
- }
- void client_list_cnt_inc(void)
- {
- _client_list *client_list_ptr = get_client_list();
-
- client_list_ptr->client_cnt++;
- }
- void client_list_cnt_dec(void)
- {
- _client_list *client_list_ptr = get_client_list();
- client_list_ptr->client_cnt--;
- }
- unsigned int get_free_client_index(void)
- {
- int i = 0;
- unsigned int id = 0;
- _client_list *client_list_ptr = get_client_list();
- for(i = 0; i < MAX_CLIENT; i++)
- {
- id = client_list_ptr->client_item[i].id;
- if( UINT_MAX == id )
- {
- break;
- }
- }
- return i;
- }
- _client_item *get_client_item(unsigned int index)
- {
- _client_list *client_list_ptr = get_client_list();
- if( index >= MAX_CLIENT )
- {
- return NULL;
- }
- return &client_list_ptr->client_item[index];
- }
- void set_client_item(unsigned int index, _client_item *client_item_ptr)
- {
- _client_list *client_list_ptr = get_client_list();
-
- if( index >= MAX_CLIENT )
- {
- return;
- }
- client_list_ptr->client_item[index] = *client_item_ptr;
- }
- SOCKET g_sk_server;
- int main()
- {
- SOCKET server;
- WSADATA wsaData;
- sockaddr_in local;
- int nRet = 0;
- int sockaddr_in_sizeof = 0;
- unsigned int index = 0;
- _client_item *client_item_ptr = NULL;
- _client_item client_item = {0};
- _client_list *client_list_ptr = NULL;
- SOCKET client;
- sockaddr_in from;
- DWORD dwThreadId;
- HANDLE hThread;
- nRet = WSAStartup(0x101, &wsaData);
- if( 0 != nRet )
- {
- return 0;
- }
-
- // 现在我们来为sockaddr_in结构赋值。
- local.sin_family = AF_INET; // 地址族
- local.sin_addr.s_addr = INADDR_ANY; // 网际IP地址
- local.sin_port = htons(LISTEN_PORT); // 使用的端口
- // 由socket函数创建我们的SOCKET。
- server = socket(AF_INET, SOCK_STREAM, 0);
- //server = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,NULL, 0, WSA_FLAG_OVERLAPPED);
- // 如果socket()函数失败,我们就退出。
- if( server == INVALID_SOCKET )
- {
- return 0;
- }
- // bind将我们刚创建的套接字和sockaddr_in结构联系起来。
- // 它主要使用本地地址及一个特定的端口来连接套接字。
- // 如果它返回非零值,就表示出现错误。
- nRet = bind(server, (sockaddr*)&local, sizeof(local));
- if( 0 != nRet )
- {
- return 0;
- }
- // listen命令套接字监听来自客户端的连接。
- // 第二个参数是最大连接数。
- nRet = listen(server, MAX_CLIENT);
- if( 0 != nRet )
- {
- return 0;
- }
- g_sk_server = server;
- // 我们需要一些变量来保存客户端的套接字,因此我们在此声明之。
- InitializeCriticalSection(&cs_serve_main);/*初始化临界区*/
- InitializeCriticalSection(&cs_serve_thread);/*初始化临界区*/
- client_list_ptr = get_client_list();
- memset(client_list_ptr, 0xff, sizeof(_client_list));
- memset(&client, 0, sizeof(SOCKET));
- memset(&from, 0, sizeof(sockaddr_in));
- sockaddr_in_sizeof = sizeof(sockaddr_in);
- while( TRUE )
- {
- index = get_free_client_index();
- if( index >= MAX_CLIENT )
- {/*已经达到最大连接数*/
- continue;
- }
- client_item_ptr = get_client_item(index);
- client_item_ptr->client = accept(server,
- (struct sockaddr*)&client_item_ptr->form, &sockaddr_in_sizeof);
- if( INVALID_SOCKET == client_item_ptr->client )
- {/*连接错误*/
- Sleep(500);
- continue;
- }else
- {
- printf("Connection from %s\n", inet_ntoa(client_item_ptr->form.sin_addr) );
- }
- /* 多线程开始*/
- EnterCriticalSection(&cs_serve_main);/*进入临界区*/
- hThread = CreateThread(
- NULL, // no security attributes
- 0, // use default stack size
- serve_client_thread_func, // thread function
- client_item_ptr, // argument to thread function
- CREATE_SUSPENDED, // use default creation flags
- &dwThreadId); // returns the thread identifier
- if( NULL != hThread )
- {
- client_item_ptr->hThread = hThread;
- client_item_ptr->dwThreadId = dwThreadId;
- client_item_ptr->id = index;
- }
- client_list_cnt_inc();
- LeaveCriticalSection(&cs_serve_main);/*离开临界区*/
- if( NULL != client_item_ptr->hThread )
- {
- ResumeThread(client_item_ptr->hThread);
- }
- client_item_ptr = NULL;
- /*end 多线程开始*/
- }
- //关闭套接字,并释放套接字描述符。
- closesocket(server);
- WSACleanup();
- DeleteCriticalSection(&cs_serve_thread);/*删除临界区*/
- DeleteCriticalSection(&cs_serve_main);/*删除临界区*/
- return 0;
- }
- void serve_client_thread_clear(SOCKET sock_client,
- sockaddr_in *sockaddr_client_ptr,
- UINT32 client_id,
- char *msg,
- _client_item *client_item_ptr
- )
- {
- int msg_len = strlen(msg);
- if( msg_len > 0 )
- {
- send(sock_client, msg, msg_len + 1, 0);
- }
- closesocket(sock_client);/*关闭连接*/
- client_list_cnt_dec();
-
- memset(client_item_ptr, 0, sizeof(_client_item));
- set_client_item(client_id, client_item_ptr);
- }
- DWORD WINAPI serve_client_thread_func(LPVOID param_ptr)
- {
- char buf[MAX_TCP_PACKET_SIZE];
- _client_item *client_item_ptr = (_client_item *)param_ptr;
- SOCKET sock_client = 0;
- sockaddr_in sockaddr_client = {0};
- unsigned int client_id = 0;
- _client_list *client_list_ptr = get_client_list();
- int recv_size = 0;
- time_t sock_free_cur_time = 0;
- time_t sock_free_kill_time = 0;
-
- int n_ret = 0;
- fd_set fdread;
- timeval tv;
- while( NULL == client_item_ptr->hThread );
- sock_client = client_item_ptr->client;
- sockaddr_client = client_item_ptr->form;
- client_id = client_item_ptr->id;
- sprintf(buf, "%s:%d you id=%d\n", inet_ntoa(sockaddr_client.sin_addr),
- sockaddr_client.sin_port, client_id);
- send(sock_client, buf, strlen(buf) + 1, 0);
- do
- {
- /*这部分代码在此处必须每次都执行*/
- FD_ZERO(&fdread);//初始化fd_set
- FD_SET(sock_client, &fdread);//分配套接字句柄到相应的fd_set
- tv.tv_sec = 1;//这里我们打算让select等待1s后返回,避免被锁死,也避免马上返回
- tv.tv_usec = 0;
- /*end 这部分代码在此处必须每次都执行*/
- select(0, &fdread, NULL, NULL, &tv);
- n_ret = FD_ISSET(sock_client, &fdread);
- if( 0 == n_ret )/*没有数据*/
- {
- continue;
- }
- recv_size = recv(sock_client, buf, sizeof(buf), 0);
- if( recv_size <= 0)
- {/*socket 错误,断开连接并退出*/
- /*超时,线程退出*/
- printf("client time out ip=%s:port=%d:id=%d\n",
- inet_ntoa(sockaddr_client.sin_addr), sockaddr_client.sin_port, client_id);
- EnterCriticalSection(&cs_serve_thread);/*进入临界区*/
- memset(buf, 0, sizeof(buf));
- serve_client_thread_clear(sock_client, &sockaddr_client, client_id, buf, client_item_ptr);
- LeaveCriticalSection(&cs_serve_thread);/*离开临界区*/
- ExitThread(0);/*退出线程*/
- }
- sock_free_cur_time = 0;
- if( ('q' == buf[0]) && (0 == buf[1]) )
- {/*客户端主动退出*/
- sprintf(buf, "client exit server ip=%s:port=%d:id=%d\n",
- inet_ntoa(sockaddr_client.sin_addr), sockaddr_client.sin_port, client_id);
- EnterCriticalSection(&cs_serve_thread);/*进入临界区*/
- serve_client_thread_clear(sock_client, &sockaddr_client, client_id, buf, client_item_ptr);
- LeaveCriticalSection(&cs_serve_thread);/*离开临界区*/
- ExitThread(0);/*退出线程*/
- }
- printf("ip=%s:port=%d:id=%d say:%s\n", inet_ntoa(sockaddr_client.sin_addr),
- sockaddr_client.sin_port, client_id, buf);
- }while( TRUE );
- return 0;
- }
头文件:client.h
- #include <winsock2.h>
- #include <stdio.h>
- #include <windef.h>
- #ifndef TCP_CLIENT_H
- #define TCP_CLIENT_H
- #pragma warning(disable : 4996)
- #define TCP_SERVER_ADDR "192.168.0.2"
- #define TCP_SERVER_PORT (60000)
- #define MAX_TCP_PACKET_SIZE (1492)/*tcp最大数据包字节数*/
- #endif/*end TCP_CLIENT_H*/
源文件:client.cpp
- #include "client.h"
- int main()
- {
- int nRet = 0;
- WORD wVersionRequested;//版本号
- WSADATA wsaData;
- SOCKET sock;
- SOCKADDR_IN server_addr;
- char buf[MAX_TCP_PACKET_SIZE];
- int recv_size = 0;
-
- wVersionRequested = MAKEWORD(1, 1);//1.1版本的套接字
- nRet = WSAStartup(wVersionRequested, &wsaData);
- if( nRet )
- {
- return nRet;
- }
-
- if (LOBYTE(wsaData.wVersion) != 1 ||
- HIBYTE(wsaData.wVersion) != 1)
- {
- return -1;
- }//判断高低字节是不是1,如果不是1.1的版本则退出
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if( INVALID_SOCKET == sock )
- {
- return -1;
- }
- server_addr.sin_addr.S_un.S_addr = inet_addr(TCP_SERVER_ADDR);
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(TCP_SERVER_PORT);
- nRet = connect(sock, (SOCKADDR*)&server_addr, sizeof(SOCKADDR) );
- if( 0 != nRet )
- {
- return nRet;
- }
- recv(sock, buf, sizeof(buf), 0);
- printf(buf);
- do
- {
- memset(buf, 0, sizeof(buf));
- printf("please write some thing:");
- gets(buf);
- send(sock, buf, strlen(buf) + 1, 0);
- if( ('q'== buf[0]) && (0 == buf[1]) )
- {
- recv_size = recv(sock, buf, sizeof(buf), 0);
- printf(buf);
- break;
- }
- }while( TRUE );
- closesocket(sock);
- WSACleanup();//必须调用这个函数清除参数
- return 0;
- }
0
上一篇:BMP之一:bmp格式解析 很容易理解
下一篇:构建基本的嵌入式Linux根文件系统
相关热门文章
- CrossFire (穿越火线)是一...
- 3月25日消息
- 手机支付好比是山上的狼...
- 11月8日
- 《玫瑰小镇》是腾讯QQ游戏...
- 10种启动故障解决方法(转)...
- 关于自动弹出网页的解决方法...
- Auto CAD 2007中文版 迅雷免费...
- 出现“high definition audio...
- 全国计算机一级考试试题...
- 修改默认端口为222,centos自...
- 用PHP做一个ftp登录页面...
- Toad for Oracle工具,为什么在...
- 本地win7安装vmw9系统winserv...
- powermt config是所什么用的...
给主人留下些什么吧!~~
评论热议
- vc简易网络服务器、客户端实现
- vc简易网络服务器、客户端实现
- 简易socket客户端和多线程服务器实现
- 简易客户端与服务器
- vc++2010实现web服务器和客户端
- [java网络编程]一个简易网络服务器的实现
- 嵌入式数据库 服务器-客户端网络访问实现
- Java实现服务器与客户端网络通信
- VC简易计算器实现
- Java网络编程学习笔记(1)用java编写客户端/服务器程序(简易)
- VC Socket 实现服务器和客户端的通讯
- 简易Web服务器实现
- 简易Web服务器实现
- VC++ MFC实现一个简易聊天(客户端篇)(逻辑解耦)
- GOLANG简易http客户端实现
- 网络编程,服务器客户端
- VC实现的简易防火墙
- C# 网络编程之Tcp实现客户端和服务器聊天
- RGB24和YUV420旋转90度的源代码
- 制作交叉工具链(龙芯)
- VC调试心得
- VS2010安装帮助文档出现错误
- BMP之一:bmp格式解析 很容易理解
- vc简易网络服务器、客户端实现
- 构建基本的嵌入式Linux根文件系统
- debian6设置网络
- 项目该怎么做
- 项目的研发步骤
- Struts源码分析
- git中文教程
- linux 中运行xp
- linux调节显示屏
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
想你到泪流
如此想你
一个男人说想你
爸爸妈妈我想跟你说
太想你了
想你收视率
开始想你了
夜越深越想你
想你的也
就是想你了
想你吗爱你吗
我想靠你
只是想你了
如果你想
只是想听听你的声音
寂寞在想你
我可想你了
而是因为想你才寂寞
我想跟懂你
我想揍你
因为想你歌词
我想你想你快疯了
想你是你在天边
韩剧想你歌曲
想你 pptv
想你的每一天歌词
你说在想我的时候
想你吧
我在这里想你
想你笑歌词
不想你
想你呀
因为想你
想你却不敢告诉你
真的很想你
我不能想你
可不可以不想你
要你
我真的好想你
不想你哭
突然很想你