Windows Socket 编程_单个服务器对多个客户端简单通讯 .

单个服务器对多个客户端程序:

一。简要说明

二。查看效果

三。编写思路

四。程序源代码

五。存在问题

 

一。简要说明:

 程序名为:TcpSocketOneServerToMulClient

 程序功能:实现单个服务器对多个客户端通讯功能的小程序。
 PS: 这是继上次简单的 Tcp Windows Socket 编程后的再一程序,程序实现依然不是很严谨,还待完善~

 

二。查看效果:

 

三。编写思路:

 由上一次的程序思路来看,如果想实现单个服务器对多个客户端程序的通讯的话,这次程序编写尝试从多线程的角度来考虑问题:

在服务器的实现中:可以main函数作为主线程,不断地接客户端的连接请求。

                                   再新建子线程——每连接一个客户端,就专为这个客户端新建一个用于实现接收信息并显示到屏幕上功能的子线程。

                                   然后,新建子线程,专用于本机发送消息。

在客户端的实现中:主线程负责连接服务器,新建子线程,用于从服务器接收信息,再建子线程,用于从客户端向服务器中发送信息。

总的来说,也可以理解为,单个服务器的进程利用这个服务器中的线程与多个客户端进程进行通讯。

 

四。程序源代码:

[cpp] view plaincopyprint?

  1. // OneServerMain.cpp   
  2.   
  3. #include <iostream>   
  4. #include <cstdio>   
  5. #include <string>   
  6. #include <cstring>   
  7. #include <vector>   
  8. #include <iterator>   
  9. #include <algorithm>   
  10. #include <Winsock2.h>   
  11. #include <Windows.h>   
  12.   
  13. using namespace std;  
  14. HANDLE bufferMutex;     // 令其能互斥成功正常通信的信号量句柄   
  15. SOCKET sockConn;        // 客户端的套接字   
  16. vector <SOCKET> clientSocketGroup;  
  17.   
  18. int main()  
  19. {  
  20. // 加载socket动态链接库(dll)   
  21.     WORD wVersionRequested;  
  22.     WSADATA wsaData;    // 这结构是用于接收Wjndows Socket的结构信息的   
  23.     wVersionRequested = MAKEWORD( 2, 2 );   // 请求2.2版本的WinSock库   
  24.     int err = WSAStartup( wVersionRequested, &wsaData );  
  25.     if ( err != 0 ) {  
  26.         return -1;          // 返回值为零的时候是表示成功申请WSAStartup   
  27.     }  
  28.     if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // 检测是否2.2版本的socket库   
  29.         WSACleanup( );  
  30.         return -1;   
  31.     }  
  32.       
  33. // 创建socket操作,建立流式套接字,返回套接字号sockSrv   
  34.     SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);     
  35.   
  36. // 套接字sockSrv与本地地址相连   
  37.     SOCKADDR_IN addrSrv;  
  38.     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 将INADDR_ANY转换为网络字节序,调用 htonl(long型)或htons(整型)   
  39.     addrSrv.sin_family = AF_INET;  
  40.     addrSrv.sin_port = htons(6000);  
  41.   
  42.     if(SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))){ // 第二参数要强制类型转换   
  43.         return -1;  
  44.     }  
  45.   
  46. // 将套接字设置为监听模式(连接请求), listen()通知TCP服务器准备好接收连接   
  47.     listen(sockSrv, 20);  
  48.   
  49.     cout << "服务器已成功就绪,若服务器想发送信息给客户端,可直接输入内容后按回车.\n";  
  50. // accept(),接收连接,等待客户端连接   
  51.   
  52.     bufferMutex = CreateSemaphore(NULL, 1, 1, NULL);   
  53.   
  54.     DWORD WINAPI SendMessageThread(LPVOID IpParameter);  
  55.     DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);  
  56.   
  57.     HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);    
  58.   
  59.     while(true){    // 不断等待客户端请求的到来   
  60.         sockConn = accept(sockSrv, NULL, NULL);  
  61.         if (SOCKET_ERROR != sockConn){  
  62.             clientSocketGroup.push_back(sockConn);  
  63.         }  
  64.         HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, (LPVOID)sockConn, 0, NULL);    
  65.         WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)    
  66.         if(NULL == receiveThread) {   
  67.             printf("\nCreatThread AnswerThread() failed.\n");   
  68.         }   
  69.         else{   
  70.             printf("\nCreate Receive Client Thread OK.\n");   
  71.         }   
  72.         ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)   
  73.     }  
  74.    
  75.     WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束   
  76.     CloseHandle(sendThread);  
  77.     CloseHandle(bufferMutex);  
  78.     WSACleanup();   // 终止对套接字库的使用   
  79.     printf("\n");  
  80.     system("pause");  
  81.     return 0;  
  82. }  
  83.   
  84.   
  85. DWORD WINAPI SendMessageThread(LPVOID IpParameter)  
  86. {  
  87.     while(1){  
  88.         string talk;  
  89.         getline(cin, talk);  
  90.         WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)     
  91.     /*  if("quit" == talk){ 
  92.             ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)  
  93.             return 0; 
  94.         } 
  95.         else*/  
  96.         {  
  97.             talk.append("\n");  
  98.         }  
  99.         printf("I Say:(\"quit\"to exit):");  
  100.         cout << talk;  
  101.         for(int i = 0; i < clientSocketGroup.size(); ++i){  
  102.     //      send(clientSocketGroup[i], talk.c_str(), talk.size(), 0);   // 发送信息   
  103.             send(clientSocketGroup[i], talk.c_str(), 200, 0);   // 发送信息   
  104.         }  
  105.         ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)    
  106.     }  
  107.     return 0;  
  108. }  
  109.   
  110.   
  111. DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)  
  112. {  
  113.     SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter;   
  114.     while(1){     
  115.         char recvBuf[300];  
  116.         recv(ClientSocket, recvBuf, 200, 0);  
  117.         WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)     
  118.   
  119.         if (recvBuf[0] == 'q' && recvBuf[1] == 'u' && recvBuf[2] == 'i' && recvBuf[3] == 't' && recvBuf[4] == '\0'){  
  120.             vector<SOCKET>::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket);  
  121.             clientSocketGroup.erase(result);  
  122.             closesocket(ClientSocket);  
  123.             ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)    
  124.             printf("\nAttention: A Client has leave...\n", 200, 0);  
  125.             break;  
  126.         }  
  127.   
  128.         printf("%s Says: %s\n", "One Client", recvBuf);     // 接收信息   
  129.           
  130.         ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)    
  131.     }  
  132.     return 0;  
  133. }  
// OneServerMain.cpp

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <iterator>
#include <algorithm>
#include <Winsock2.h>
#include <Windows.h>

using namespace std;
HANDLE bufferMutex;		// 令其能互斥成功正常通信的信号量句柄
SOCKET sockConn;		// 客户端的套接字
vector <SOCKET> clientSocketGroup;

int main()
{
// 加载socket动态链接库(dll)
	WORD wVersionRequested;
	WSADATA wsaData;	// 这结构是用于接收Wjndows Socket的结构信息的
	wVersionRequested = MAKEWORD( 2, 2 );	// 请求2.2版本的WinSock库
	int err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {
		return -1;			// 返回值为零的时候是表示成功申请WSAStartup
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 2 ) { // 检测是否2.2版本的socket库
		WSACleanup( );
		return -1;
	}

// 创建socket操作,建立流式套接字,返回套接字号sockSrv
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);	

// 套接字sockSrv与本地地址相连
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // 将INADDR_ANY转换为网络字节序,调用 htonl(long型)或htons(整型)
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);

	if(SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))){ // 第二参数要强制类型转换
		return -1;
	}

// 将套接字设置为监听模式(连接请求), listen()通知TCP服务器准备好接收连接
	listen(sockSrv, 20);

	cout << "服务器已成功就绪,若服务器想发送信息给客户端,可直接输入内容后按回车.\n";
// accept(),接收连接,等待客户端连接

	bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); 

	DWORD WINAPI SendMessageThread(LPVOID IpParameter);
	DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);

	HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);  

	while(true){	// 不断等待客户端请求的到来
		sockConn = accept(sockSrv, NULL, NULL);
		if (SOCKET_ERROR != sockConn){
			clientSocketGroup.push_back(sockConn);
		}
		HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, (LPVOID)sockConn, 0, NULL);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)
		if(NULL == receiveThread) {
			printf("\nCreatThread AnswerThread() failed.\n");
		}
		else{
			printf("\nCreate Receive Client Thread OK.\n");
		}
		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
	}

	WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束
	CloseHandle(sendThread);
	CloseHandle(bufferMutex);
	WSACleanup();	// 终止对套接字库的使用
	printf("\n");
	system("pause");
	return 0;
}

DWORD WINAPI SendMessageThread(LPVOID IpParameter)
{
	while(1){
		string talk;
		getline(cin, talk);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)
	/*	if("quit" == talk){
			ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
			return 0;
		}
		else*/
		{
			talk.append("\n");
		}
		printf("I Say:(\"quit\"to exit):");
		cout << talk;
		for(int i = 0; i < clientSocketGroup.size(); ++i){
	//		send(clientSocketGroup[i], talk.c_str(), talk.size(), 0);	// 发送信息
			send(clientSocketGroup[i], talk.c_str(), 200, 0);	// 发送信息
		}
		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
	}
	return 0;
}

DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)
{
	SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter;
	while(1){
		char recvBuf[300];
		recv(ClientSocket, recvBuf, 200, 0);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)  

		if (recvBuf[0] == 'q' && recvBuf[1] == 'u' && recvBuf[2] == 'i' && recvBuf[3] == 't' && recvBuf[4] == '\0'){
			vector<SOCKET>::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket);
			clientSocketGroup.erase(result);
			closesocket(ClientSocket);
			ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
			printf("\nAttention: A Client has leave...\n", 200, 0);
			break;
		}

		printf("%s Says: %s\n", "One Client", recvBuf);		// 接收信息

		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
	}
	return 0;
}

 

[cpp] view plaincopyprint?

  1. // MulClientMain.cpp   
  2.   
  3. #include <iostream>   
  4. #include <cstdio>   
  5. #include <string>   
  6. #include <cstring>   
  7. #include <winsock2.h>   
  8. #include <Windows.h>   
  9.   
  10. using namespace std;  
  11.   
  12. SOCKET sockClient;      // 连接成功后的套接字   
  13. HANDLE bufferMutex;     // 令其能互斥成功正常通信的信号量句柄   
  14.   
  15. int main()  
  16. {  
  17. // 加载socket动态链接库(dll)   
  18.     WORD wVersionRequested;  
  19.     WSADATA wsaData;    // 这结构是用于接收Wjndows Socket的结构信息的   
  20.     wVersionRequested = MAKEWORD( 2, 2 );   // 请求2.2版本的WinSock库   
  21.     int err = WSAStartup( wVersionRequested, &wsaData );  
  22.     if ( err != 0 ) {   // 返回值为零的时候是表示成功申请WSAStartup   
  23.         return -1;  
  24.     }  
  25.     if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // 检查版本号是否正确   
  26.         WSACleanup( );  
  27.         return -1;   
  28.     }  
  29.       
  30. // 创建socket操作,建立流式套接字,返回套接字号sockClient   
  31.      sockClient = socket(AF_INET, SOCK_STREAM, 0);  
  32.      if(sockClient == INVALID_SOCKET) {   
  33.         printf("Error at socket():%ld\n", WSAGetLastError());   
  34.         WSACleanup();   
  35.         return -1;   
  36.       }   
  37.   
  38. // 将套接字sockClient与远程主机相连   
  39.     // int connect( SOCKET s,  const struct sockaddr* name,  int namelen);   
  40.     // 第一个参数:需要进行连接操作的套接字   
  41.     // 第二个参数:设定所需要连接的地址信息   
  42.     // 第三个参数:地址的长度   
  43.     SOCKADDR_IN addrSrv;  
  44.     addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");      // 本地回路地址是127.0.0.1;    
  45.     addrSrv.sin_family = AF_INET;  
  46.     addrSrv.sin_port = htons(6000);  
  47.     connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));  
  48.     cout << "本客户端已准备就绪,用户可直接输入文字向服务器反馈信息。\n";  
  49.   
  50. //  send(sockClient, "\nAttention: A Client has enter...\n", strlen("Attention: A Client has enter...\n")+1, 0);   
  51.     send(sockClient, "\nAttention: A Client has enter...\n", 200, 0);  
  52.   
  53.     bufferMutex = CreateSemaphore(NULL, 1, 1, NULL);   
  54.   
  55.     DWORD WINAPI SendMessageThread(LPVOID IpParameter);  
  56.     DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);  
  57.   
  58.     HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);    
  59.     HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, NULL, 0, NULL);    
  60.   
  61.          
  62.     WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束   
  63.     closesocket(sockClient);  
  64.     CloseHandle(sendThread);  
  65.     CloseHandle(receiveThread);  
  66.     CloseHandle(bufferMutex);  
  67.     WSACleanup();   // 终止对套接字库的使用   
  68.   
  69.     printf("End linking...\n");  
  70.     printf("\n");  
  71.     system("pause");  
  72.     return 0;  
  73. }  
  74.   
  75.   
  76. DWORD WINAPI SendMessageThread(LPVOID IpParameter)  
  77. {  
  78.     while(1){  
  79.         string talk;  
  80.         getline(cin, talk);  
  81.         WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)     
  82.         if("quit" == talk){  
  83.             talk.push_back('\0');  
  84. //          send(sockClient, talk.c_str(), talk.size(), 0);   
  85.             send(sockClient, talk.c_str(), 200, 0);  
  86.             break;  
  87.         }  
  88.         else{  
  89.             talk.append("\n");  
  90.         }  
  91.         printf("\nI Say:(\"quit\"to exit):");  
  92.         cout << talk;       
  93.     //  send(sockClient, talk.c_str(), talk.size(), 0); // 发送信息   
  94.         send(sockClient, talk.c_str(), 200, 0); // 发送信息   
  95.         ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)    
  96.     }  
  97.     return 0;  
  98. }  
  99.   
  100.   
  101. DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)  
  102. {  
  103.     while(1){     
  104.         char recvBuf[300];  
  105.         recv(sockClient, recvBuf, 200, 0);  
  106.         WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)     
  107.   
  108.         printf("%s Says: %s\n", "Server", recvBuf);     // 接收信息   
  109.           
  110.         ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)    
  111.     }  
  112.     return 0;  
  113. }  
// MulClientMain.cpp

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <winsock2.h>
#include <Windows.h>

using namespace std;

SOCKET sockClient;		// 连接成功后的套接字
HANDLE bufferMutex;		// 令其能互斥成功正常通信的信号量句柄

int main()
{
// 加载socket动态链接库(dll)
	WORD wVersionRequested;
	WSADATA wsaData;	// 这结构是用于接收Wjndows Socket的结构信息的
	wVersionRequested = MAKEWORD( 2, 2 );	// 请求2.2版本的WinSock库
	int err = WSAStartup( wVersionRequested, &wsaData );
	if ( err != 0 ) {	// 返回值为零的时候是表示成功申请WSAStartup
		return -1;
	}
	if ( LOBYTE( wsaData.wVersion ) != 2 ||	HIBYTE( wsaData.wVersion ) != 2 ) { // 检查版本号是否正确
		WSACleanup( );
		return -1;
	}

// 创建socket操作,建立流式套接字,返回套接字号sockClient
	 sockClient = socket(AF_INET, SOCK_STREAM, 0);
	 if(sockClient == INVALID_SOCKET) {
		printf("Error at socket():%ld\n", WSAGetLastError());
        WSACleanup();
        return -1;
      } 

// 将套接字sockClient与远程主机相连
	// int connect( SOCKET s,  const struct sockaddr* name,  int namelen);
	// 第一个参数:需要进行连接操作的套接字
	// 第二个参数:设定所需要连接的地址信息
	// 第三个参数:地址的长度
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");		// 本地回路地址是127.0.0.1;
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	cout << "本客户端已准备就绪,用户可直接输入文字向服务器反馈信息。\n";

//	send(sockClient, "\nAttention: A Client has enter...\n", strlen("Attention: A Client has enter...\n")+1, 0);
	send(sockClient, "\nAttention: A Client has enter...\n", 200, 0);

	bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); 

	DWORD WINAPI SendMessageThread(LPVOID IpParameter);
	DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);

	HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);
	HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, NULL, 0, NULL);  

    WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束
	closesocket(sockClient);
	CloseHandle(sendThread);
	CloseHandle(receiveThread);
	CloseHandle(bufferMutex);
	WSACleanup();	// 终止对套接字库的使用

	printf("End linking...\n");
	printf("\n");
	system("pause");
	return 0;
}

DWORD WINAPI SendMessageThread(LPVOID IpParameter)
{
	while(1){
		string talk;
		getline(cin, talk);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)
		if("quit" == talk){
			talk.push_back('\0');
//			send(sockClient, talk.c_str(), talk.size(), 0);
			send(sockClient, talk.c_str(), 200, 0);
			break;
		}
		else{
			talk.append("\n");
		}
		printf("\nI Say:(\"quit\"to exit):");
		cout << talk;
	//	send(sockClient, talk.c_str(), talk.size(), 0);	// 发送信息
		send(sockClient, talk.c_str(), 200, 0);	// 发送信息
		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
	}
	return 0;
}

DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)
{
	while(1){
		char recvBuf[300];
		recv(sockClient, recvBuf, 200, 0);
		WaitForSingleObject(bufferMutex, INFINITE);		// P(资源未被占用)  

		printf("%s Says: %s\n", "Server", recvBuf);		// 接收信息

		ReleaseSemaphore(bufferMutex, 1, NULL);		// V(资源占用完毕)
	}
	return 0;
}

 

五。存在问题:

       1. 将客户端异常退出(不按程序要求输入“quit”退出),而直接用ALT+F4关闭后,服务器会出现死循环显示乱码的情况。

       2. 在未启动服务器前提下,直接启动客户端时出现死循环乱码情况。

       3. 服务器输入“quit”时不能正常退出。

 

 

from:http://blog.csdn.net/neicole/article/details/7539444

时间: 2024-11-03 00:22:51

Windows Socket 编程_单个服务器对多个客户端简单通讯 .的相关文章

Windows Socket 编程_ 简单的服务器/客户端程序 .

一.程序运行效果图 二.程序源代码 三.程序设计相关基础知识     1.计算机网络    2.IP地址    3.协议    4.网络体系结构    5.TCP/IP体系结构与特点    6.客户机/服务器模式    7.TCP/IP特点    8.套接字的引入    9.面向 连接/无连接 的套接字的系统调用时序图/流程图   一.程序运行效果图   二.程序源代码 [cpp] view plaincopyprint? // server.cpp       #include <iostre

windows socket编程客户端怎么使用recv函数接受服务器发送的大数据

问题描述 windows socket编程客户端怎么使用recv函数接受服务器发送的大数据 我写了个客户端接受服务器的数据,用recv接收,当缓冲区的大小小于发送的数据的大小后 要怎么处理recv函数,本人刚开始学习socket编程,还望大神们赐教啊!!!!! 解决方案 用while循环一直recv就可以了 解决方案二: 一直recv就可以了 解决方案三: 服务器和客户端两边的数据都安固定大小重复发送收取.可以把大小放小一些比较灵活,比如4096个字节

在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分

编程|网络|异步 ///////////////////////////////////////////////////////////////////////////////////////////* 标题:在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分 当看到.NET中TcpListener和TcpClient的时候,我非常高兴,那就是我想要的通讯模式但是使用之后发现它们的力量太单薄了,我们需要一个更好的类库来替代它们. 下面提供了一些类,可以

关于windows下socket编程的recv函数

问题描述 关于windows下socket编程的recv函数 Talk is cheap,show me the code. do{ memset(buf, 0, BUFSIZ); strLen = recv(reads.fd_array[i], buf, BUFSIZ - 1, 0); if (strLen == 0 || strLen == -1){ FD_CLR(reads.fd_array[i], &reads); closesocket(cpyReads.fd_array[i]); p

读懂Java中的Socket编程(转)

Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序.  餐前甜点  Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对

教你轻松读懂Java中的Socket编程

餐前甜点 Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对这个对象进行一次或多次的读取或写入操作.Read操作用来从IO操作对象读取数据,并将数据传递给用户进程.Write操作用来将用户进程中的数据传递(写入)到IO操作对象. 当所有的Read和Write操作结束之后,用户进程需要调用Close来通知系统其完成对

《windows核心编程系列》二谈谈ANSI和Unicode字符集 .

http://blog.csdn.net/ithzhang/article/details/7916732转载请注明出处!! 第二章:字符和字符串处理     使用vc编程时项目-->属性-->常规栏下我们可以设置项目字符集合,它可以是ANSI(多字节)字符集,也可以是unicode字符集.一般情况下说Unicode都是指UTF-16.也就是说每个字符编码为两个字节.65535个字符可以表示世界上大部分的语言.为了软件使国际化大家再编程时应该使用unicode字符集.由于原来学过c语言,不习惯

【转】Windows Socket网络编程(二)----套接字编程原理

Windows Socket 网络编程(二) -- 套接字编程原理作者: 冰点工作室 小鹰 一.客户机/服务器模式在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model).该模式的建立基于以下两点:1.非对等作用:2.通信完全是异步的.客户机/服务器模式在操作过程中采取的是主动请示方式: 首先服务器方要先启动,并根据请示提供相应服务:(过程如下)1.打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求.2.等待客户请求到达该端

Linux Socket编程获取服务器时间

客户端向服务器端发送请求,服务器收到请求做相应的处理,将处理结果传回客户端.下面采用TCP协议实现服务器和客户端之间的连接. 1. 客户端 约定双方的传输协议(UDP或者TCP),根据传输协议创建socket: 服务器的IP地址和端口号: 连接服务器: 获取服务器传递回来的数据. #include<string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #i