1. 程式人生 > >windows下socket程式設計,多執行緒

windows下socket程式設計,多執行緒

sercer端

#include <stdio.h>
#include <process.h>
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
void send(void *a);
void showIP();
SOCKET sockConn;
SOCKADDR_IN addrClient;//連線上的客戶端IP地址
void main() 
{
	printf("server's information\n");
	showIP();


	WORD wVersionRequested;   
	WSADATA wsaData;   
	int err;
	wVersionRequested = MAKEWORD(1,1);
	err = WSAStartup(wVersionRequested,&wsaData);
	if ( err != 0 )  
	{
		return; 
	}
	if (LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )  
	{      
		WSACleanup();
		return;   
	}
	//構造監聽SOCKET,流式SOCKET
	SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); 


	//配置監聽地址和埠:
	SOCKADDR_IN addrSrv;   
	addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);  
	addrSrv.sin_family=AF_INET;  
	addrSrv.sin_port=htons(6003); 


	bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//繫結埠  
	listen(sockSrv,5);
	  
	int len=sizeof(SOCKADDR); 
	sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //接受客戶端連線,獲取客戶端的IP地址   


	_beginthread(send,0,NULL);
	char recvBuf[50];


	while(1)
	{    
		//char sendBuf[50];
		//char sendMes[50];
		//scanf("%s",sendMes);
		//printf("-->:%s\n",sendMes);
		//sprintf(sendBuf,sendMes,inet_ntoa(addrClient.sin_addr));//組合訊息傳送出去   
		//send(sockConn,sendBuf,strlen(sendBuf)+1,0);//傳送訊息到客戶端   
		//
		recv(sockConn,recvBuf,50,0);//接受客戶端訊息   
		printf("<--:%s\n",recvBuf);
	}
	closesocket(sockConn);//斷開連線  
} 




void send(void *a)
{
	char sendBuf[50];
	char sendMes[50];
	while (1)
	{
		gets(sendMes);
		printf("-->:%s\n",sendMes);
		sprintf(sendBuf,sendMes,inet_ntoa(addrClient.sin_addr));//組合訊息傳送出去   
		send(sockConn,sendBuf,strlen(sendBuf)+1,0);//傳送訊息到客戶端  		
	}
	_endthread();
}


void showIP() //定義CheckIP()函式,用於獲取本機IP地址 
{
	WSADATA wsaData;
	char name[20];//定義用於存放獲得的主機名的變數 
	char *ip;//定義IP地址變數 
	PHOSTENT hostinfo; 


	//呼叫MAKEWORD()獲得Winsock版本的正確值,用於載入Winsock庫 
	if ( WSAStartup( MAKEWORD(2,0), &wsaData ) == 0 ) { 
		//現在是載入Winsock庫,如果WSAStartup()函式返回值為0,說明載入成功,程式可以繼續 
		if( gethostname ( name, sizeof(name)) == 0) { 
			//如果成功地將本地主機名存放入由name引數指定的緩衝區中 
			if((hostinfo = gethostbyname(name)) != NULL) { 
				//這是獲取主機名,如果獲得主機名成功的話,將返回一個指標,指向hostinfo,hostinfo 
				//為PHOSTENT型的變數,下面即將用到這個結構體 
				ip = inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list); 
				//呼叫inet_ntoa()函式,將hostinfo結構變數中的h_addr_list轉化為標準的點分表示的IP 
				//地址(如192.168.0.1) 
				printf("%s\n",ip);//輸出IP地址
				printf("%s\n",name);
			} 
		} 
		WSACleanup();//解除安裝Winsock庫,並釋放所有資源 
	}
} 


client端
#include <stdio.h> 
#include <Winsock2.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")  
SOCKET sockClient;
void send(void *p);
void main()
{      
	WORD wVersionRequested;      
	WSADATA wsaData;//WSAata用來儲存系統傳回的關於WinSocket的資訊     
	int err;      
	wVersionRequested = MAKEWORD(1,1);      
	err = WSAStartup( wVersionRequested, &wsaData);  
	if ( err != 0 )  
	{
		return;     
	}
	if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 )      
	{          
		WSACleanup();
		return;     
	}      
	sockClient=socket(AF_INET,SOCK_STREAM,0);//AF_INET表示TCP連線     //初始化連線與埠號     
	SOCKADDR_IN addrSrv;  
	char IP[20];
	printf("Please input server's IP:  ");
	scanf("%s",IP);
	addrSrv.sin_addr.S_un.S_addr=inet_addr(IP);//本機地址,伺服器在本機開啟     
	addrSrv.sin_family=AF_INET;      
	addrSrv.sin_port=htons(6003);//設定埠號
	connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//連線伺服器
	int hand = _beginthread(send,0,NULL);
	char recvBuf[50];
	while (1)
	{
		
		//char sendMes[50];
		//scanf("%s",sendMes);
		recv(sockClient,recvBuf,50,0);//接受資料
		printf("<--:%s\n",recvBuf);
		//printf("-->:%s\n",sendMes);
		//send(sockClient,sendMes,strlen(sendMes)+1,0);//傳送資料 
		
	}
	closesocket(sockClient);//關閉連線      
	WSACleanup();
	system("pause");
}


void send(void *p)
{
	char sendMes[50];
	while (1)
	{
		gets(sendMes);
		printf("-->:%s\n",sendMes);
		send(sockClient,sendMes,strlen(sendMes)+1,0);//傳送資料 
	}
	_endthread();
}