windows下socket编程实现client和server双向通信

Posted wuyepeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}

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

技术分享图片

 

以上是关于windows下socket编程实现client和server双向通信的主要内容,如果未能解决你的问题,请参考以下文章

python,socket网络编程,最简单的server端和client端代码

Socket编程的简单实现

Python Socket Client及Server简单编程

python socket编程

Java 通过Socket编程 发送和接收数据

socket编程server端程序接收client连接后accept套接字值为0正常吗?