標籤:tcp socket 通訊端 通訊 資料轉送
XX:那飄過的100~_~{2014/10/02 16:12}
流式通訊端(SOCK_STREAM):提供連線導向、可靠的Data Transmission Service、資料無差錯、無重複的發送、且按發送順序接受。程式的設計思路
伺服器端:
流程:WSAStartup()->socket()->bind()->listen()->accept()->send()
(1)建立通訊端
(2)將通訊端綁定到一個本地地址和連接埠上
(3)將通訊端設為監聽模式,準備接受用戶端的請求
(4)等待用戶端請求的到來,當請求到來後,接受串連請求,返回一個對應與此次串連的通訊端
(5)用返回的通訊端與用戶端進行通訊
(6)返回,等待另一個用戶端的串連請求
(7)關閉通訊端
// socketTcp.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "tchar.h"#pragma comment(lib,"wsock32.lib")#include <stdio.h>#include <winsock2.h>#define MAX_SER 10#define HOST_PATH 256#define HOSTNAME_SIZE HOST_PATHchar hostName[MAX_PATH]={0};unsigned short maxService;unsigned short port;void Service(LPVOID lpv);int LoopControl(SOCKET llistenfd,int isMultiTasking);void initial();int initSockets(void);//初始化Windows Socketint main(int argc, char * argv[]) {SOCKET listenFd; struct sockaddr_in serverAddr;int err;initial();initSockets();//建立socketlistenFd=socket(PF_INET,SOCK_STREAM,0);if(listenFd==INVALID_SOCKET){printf("error:out of socket resource \n");return 1;}//bind原生連接埠serverAddr.sin_family=PF_INET;//協議類型是INETserverAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//本機IPserverAddr.sin_port=htons(port);//綁定連接埠為5054err=bind(listenFd,(const struct sockaddr *)&serverAddr,sizeof(serverAddr));if(err==INVALID_SOCKET){printf("error: unable to bind socket \n");return 1;}//listen 監聽連接埠err=listen(listenFd,3);if(err==INVALID_SOCKET){printf("error: listen socket failed \n");return 1;}printf("listen......");LoopControl(listenFd,1);printf("server is down \n");WSACleanup();return 0;}void initial(){maxService=3;port=5054;} /* *Winsock服務初始化 */int initSockets(void){WSADATA wsaData;WORD sockVersion; //typedef unsigned short WORD(16)int err;sockVersion=MAKEWORD(2,2);err=WSAStartup(sockVersion,&wsaData); if(err!=0){printf("error %d :winsock not avaliable\n",err);}printf("environemnt invaild success.....\n");return 0;}/*** 等待用戶端的串連*/int LoopControl(SOCKET listenfd,int isMultiTasking){SOCKET acceptfd;struct sockaddr_in clientAddr;//用戶端地址資訊int err;int serverNum=0;HANDLE handles[MAX_SER];int nSize;nSize=sizeof(clientAddr);int myID;//存在固定的次數[服務次數小於最大服務次數]while(serverNum<maxService){acceptfd=accept(listenfd,(struct sockaddr *)&clientAddr,&nSize);//接收客戶串連的準備if(acceptfd==INVALID_SOCKET){printf("error:accept failed \n");return 1;}printf("accepted connection from client at %s \n",inet_ntoa(clientAddr.sin_addr));if(isMultiTasking){handles[serverNum]=CreateThread(NULL,1000,(LPTHREAD_START_ROUTINE)Service,(LPVOID)acceptfd,0,(unsigned long *)&myID);}else{Service((LPVOID)acceptfd);}serverNum++;}if(isMultiTasking){err=WaitForMultipleObjects(maxService,handles,TRUE,INFINITE);printf("last thread to finish was thread # %d \n",err);}return 0;}/**接收用戶端的資料,AND向用戶端發送資料*/void Service(LPVOID lpv){SOCKET acceptfd=(SOCKET)lpv;const char *msg="message have recived";char response[4096];memset(response,0,sizeof(response));while(acceptfd!=SOCKET_ERROR){int result=recv(acceptfd,response,sizeof(response),0);//接受客戶機的資料if(result>0){printf("from client: %s ",response);send(acceptfd,msg,strlen(msg)+1,0);}}closesocket(acceptfd);}
在瀏覽器中輸入本地ip:5054,查看運行效果。或者使用netstat -a查看連接埠狀態
TCP的Socket技術之伺服器端