zoukankan      html  css  js  c++  java
  • windows下socket编程实现client和server双向通信

    服务端代码server.c

    // server.cpp : Defines the entry point for the console application.
    //
    
    #include <stdio.h>
    #include <Winsock2.h>	//Socket的函数调用 
    #include <windows.h>
    
    #define BUF_SIZE 6400  //  缓冲区大小 
    
    #pragma comment (lib, "ws2_32")		// 使用WINSOCK2.H时,则需要库文件WS2_32.LIB
    
    DWORD WINAPI Rcv( LPVOID lpParam )
    {
    	SOCKET sClient = *(SOCKET*)lpParam;
    	int retVal;
    	char bufRecv[BUF_SIZE]; 
    	memset( bufRecv, 0, sizeof( bufRecv ) );
    	while(1)
    	{
    		retVal = recv( sClient, bufRecv, BUF_SIZE, 0 );
    		if ( retVal == SOCKET_ERROR ) {
    			printf( "recive faild!
    " );
    			break;
    		} else {
    			printf( "收到客户端消息:%s
    ", bufRecv );
    		} 
    	}
    	return 0;
    }
    
    DWORD WINAPI Snd( LPVOID lpParam )
    {
    	SOCKET sClient = *(SOCKET*)lpParam;
    	int retVal;
    	char bufSend[BUF_SIZE]; 
    	memset( bufSend, 0, sizeof( bufSend ) );
    	while(1)
    	{
    		gets( bufSend );
    		retVal = send( sClient, bufSend, strlen(bufSend)+sizeof(char), 0 );
    		if ( retVal == SOCKET_ERROR ) {
    			printf( "send faild!
    " );
    			break;
    		} 
    	}
    	return 0;
    }
    
    
    int main(int argc, char* argv[])
    {
    	// 初始化套接字动态库
    	WSADATA wsaData;
    	if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0 ) {
    		printf( "winsock load faild!
    " );
    		return 1;
    	}
    	
    	//  创建服务段套接字 
    	SOCKET sServer = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    	if ( sServer == INVALID_SOCKET ) {
    		printf( "socket faild!
    " );
    		WSACleanup();
    		return -1;
    	}
    	
    	//  服务端地址 
    	sockaddr_in addrServ;
    
    	addrServ.sin_family = AF_INET; 
    	addrServ.sin_port = htons( 9999 );
    	addrServ.sin_addr.s_addr = htonl( INADDR_ANY ); 
    	
    	//  绑定套接字 
    	if ( bind( sServer, ( const struct sockaddr* )&addrServ, sizeof(addrServ) ) == SOCKET_ERROR ) {
    		printf( "bind faild!
    " );
    		closesocket( sServer );
    		WSACleanup(); 
    		return -1;
    	} 
    	
    	printf("Server is On IP:[%s],port:[%d]
    ",inet_ntoa(addrServ.sin_addr),ntohs(addrServ.sin_port)); 
    	
    	//  监听套接字  数字表示最多能监听客户个数 
    	if ( listen( sServer, 5 ) == SOCKET_ERROR ) {
    		printf( "listen faild!
    " );
    		closesocket( sServer );
    		WSACleanup();
    		return -1; 
    	} 
    	
    	SOCKET sClient; //  客户端套接字
    	
    	sockaddr_in addrClient;
    	int addrClientLen = sizeof( addrClient );
    	
    	
    	sClient = accept( sServer, ( sockaddr FAR* )&addrClient, &addrClientLen ); 
    	if ( sClient == INVALID_SOCKET ) {
    		printf( "accept faild!
    " );
    		closesocket( sServer );
    		WSACleanup();
    		return -1; 
    	}
    	printf("accepted client IP:[%s],port:[%d]
    ",inet_ntoa(addrClient.sin_addr),ntohs(addrClient.sin_port));
    	
    	HANDLE hThread1, hThread2;
    	DWORD dwThreadId1, dwThreadId2;
    
    	hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, 0, &dwThreadId1);
    	hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, 0, &dwThreadId2);
    
    	::WaitForSingleObject(hThread1, INFINITE);
    	::WaitForSingleObject(hThread2, INFINITE);
    	::CloseHandle(hThread1);
    	::CloseHandle(hThread2);
    		
    	closesocket( sClient ); 
    	WSACleanup(); // 资源释放
    
    	return 0;
    }
    

    客户端代码client.c

    // client.cpp : Defines the entry point for the console application.
    //
    
    #include <stdio.h>
    #include <Winsock2.h>	//Socket的函数调用 
    #include <windows.h>
    
    #define BUF_SIZE 6400
    
    #pragma comment (lib, "ws2_32")		// 使用WINSOCK2.H时,则需要库文件WS2_32.LIB
    
    DWORD WINAPI Rcv( LPVOID lpParam )
    {
    	SOCKET sHost = *(SOCKET*)lpParam;
    	int retVal;
    	char bufRecv[BUF_SIZE]; 
    	memset( bufRecv, 0, sizeof( bufRecv ) );
    	while(1)
    	{
    		retVal = recv( sHost, bufRecv, BUF_SIZE, 0 );
    		if ( retVal == SOCKET_ERROR ) {
    			printf( "recive faild!
    " );
    			break;
    		} else {
    			printf( "收到服务器消息:%s
    ", bufRecv );
    		} 
    	}
    	return 0;
    }
    
    DWORD WINAPI Snd( LPVOID lpParam )
    {
    	SOCKET sHost = *(SOCKET*)lpParam;
    	int retVal;
    	char bufSend[BUF_SIZE]; 
    	memset( bufSend, 0, sizeof( bufSend ) );
    	while(1)
    	{
    		gets( bufSend );
    		retVal = send( sHost, bufSend, strlen(bufSend)+sizeof(char), 0 );
    		if ( retVal == SOCKET_ERROR ) {
    			printf( "send faild!
    " );
    			break;
    		} 
    	}
    	return 0;
    }
    
    int main(int argc, char* argv[])
    {
    	WSADATA wsaData;
    	if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 ) {
    		printf( "Winsock load faild!
    " );
    		return 1;
    	}
    	
    	//  服务器套接字 
    	SOCKET sHost = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    	if ( sHost == INVALID_SOCKET ) {
    		printf( "socket faild!
    " );
    		WSACleanup();
    		return -1;
    	}
    	
    	SOCKADDR_IN servAddr;
    	servAddr.sin_family = AF_INET;
    	//  注意   当把客户端程序发到别人的电脑时 此处IP需改为服务器所在电脑的IP 
    	servAddr.sin_addr.S_un.S_addr = inet_addr( "127.0.0.1" );
    	servAddr.sin_port = htons( 9999 );
    	
    	//  连接服务器
    	if ( connect( sHost, (LPSOCKADDR)&servAddr, sizeof( servAddr ) ) == SOCKET_ERROR ) {
    		printf( "connect faild!
    " );
    		closesocket(sHost);
    		WSACleanup();
    		return -1;
    	} 
    	printf("连接到服务器 IP:[%s],port:[%d]
    ",inet_ntoa(servAddr.sin_addr),ntohs(servAddr.sin_port));
    
    	HANDLE hThread1, hThread2;
    	DWORD dwThreadId1, dwThreadId2;
    
    	hThread1 = ::CreateThread( NULL, NULL, Snd, (LPVOID)&sHost, 0, &dwThreadId1 );
    	hThread2 = ::CreateThread( NULL, NULL, Rcv, (LPVOID)&sHost, 0, &dwThreadId2 );
    	
    	::WaitForSingleObject( hThread1, INFINITE );
    	::WaitForSingleObject( hThread2, INFINITE );
    	::CloseHandle(hThread1);
    	::CloseHandle(hThread2);
    
    
    	closesocket(sHost);
    	WSACleanup(); 
    	return 0;
    }
    

    截图如下:编译好后首先是启动服务端(来监听),然后再启动客户端

  • 相关阅读:
    HTML标签大全
    PHP实现QQ第三方登录代码
    php链接access并查询列出
    php连接Access数据库
    获取文件信息
    动态网页转伪静态
    asp读取指定目录下的文件名
    如何设置VBA代码的密码?如何取消VBA代码的密码?
    ol序号并在序号加背景色
    免费ASP空间
  • 原文地址:https://www.cnblogs.com/wuyepeng/p/9726844.html
Copyright © 2011-2022 走看看