TCP 編程。




sockets(套接字)編程有三種,流式套接字(SOCK_STREAM)TCP,數據報套接字UDP(SOCK_DGRAM),原始套接字(SOCK_RAW);基於TCP的socket編程是採用的流式套接字。
在這個程序中,將兩個工程添加到一個工作區。要鏈接一個ws2_32.lib的庫文件。
服務器端編程的步驟:
1:加載套接字庫,創建套接字(WSAStartup()/socket());
2:綁定套接字到一個IP地址和一個端口上(bind());
3:將套接字設置爲監聽模式等待連接請求(listen());
4:請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept());
5:用返回的套接字和客戶端進行通信(send()/recv());
6:返回,等待另一連接請求;
7:關閉套接字,關閉加載的套接字庫(closesocket()/WSACleanup())。


以下是服務器端代碼如下(VC項目應建立在windows控制檯模式下的應用程序):


#include <stdio.h>
#include <Winsock2.h>
void main()
{
 WORD wVersionRequested;              //版本號
 WSADATA wsaData;                        //啓動SOCKET的
 int err;
 
 wVersionRequested = MAKEWORD( 1, 1 );//建立版本
 
 err = WSAStartup( wVersionRequested, &wsaData );//啓用socket
 if ( err != 0 ) //如果返回值不等於0,那麼表示出錯,直截退出程序
{
  return;
}
 
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);    //設置爲TCP流模式


 SOCKADDR_IN addrSrv;                                                        //
 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);            //INADDR_ANY爲本機任意IP
 addrSrv.sin_family=AF_INET;                                                //
 addrSrv.sin_port=htons(6000);                                                //偵聽端口爲6000
 
 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));    //綁定到SOCKET
 listen(sockSrv, 5);                                    //偵聽sockSrv,並設置最大客戶連接數爲5。


 SOCKADDR_IN addrClient;           
 int len=sizeof(SOCKADDR);
 while(1)
 {
  SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len); //等待客戶連接,如果沒有客戶連接時,則此函數在這裏會產生阻塞。
  char sendBuf[50];
  sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
  send(sockConn,sendBuf,strlen(sendBuf)+1,0);    //發送sendBuf的字符串給客戶端。
  char recvBuf[50];
  recv(sockConn,recvBuf,50,0);                                //從客戶端接收50個字節。
  printf("%s\n",recvBuf);                                    //顯示客戶端發過來的字符串
  closesocket(sockConn);                                //關閉字
 }
 WSACleanup();                        //清理
}
很簡單吧?呵呵。再複雜的使用TCP協議的網絡通信程序也是基於此的。下面順便也把客戶端的程序寫出來。相同部分的程序就不不註釋了。


客戶端編程的步驟:
1:加載套接字庫,創建套接字(WSAStartup()/socket());
2:向服務器發出連接請求(connect());
3:和服務器端進行通信(send()/recv());
4:關閉套接字,關閉加載的套接字庫(closesocket()/WSACleanup())。
客戶端的代碼如下:
#include <stdio.h>
#include <Winsock2.h>
void main()
{
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 
 wVersionRequested = MAKEWORD( 1, 1 );
 
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 ) {
  return;
 }
 
  SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
 
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");//設置SOCKET的IP爲本機。
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(6000);//端口爲6000,服務端和客戶端的端口一定要相同.否則是連不上的
 connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));//根據addrSrv連接服務端
 char recvBuf[50];
 recv(sockClient,recvBuf,50,0);                        //接收50字符
 printf("%s\n",recvBuf);        //顯示
 send(sockClient,"hello",strlen("hello")+1,0);    //發送一個hello
 
 closesocket(sockClient);            //關閉
 WSACleanup();                        //清理
}


對了,在這種模式叫做什麼同步阻塞模式,遇到連接,發送,接受函數時,程序便會等待,直到完成操作,纔會執行下面的程序段,所以一般這些網絡操作都會開啓一個新線程去完成,那樣不會使程序的主線程阻塞。呵呵。容易吧?``
發佈了82 篇原創文章 · 獲贊 22 · 訪問量 23萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章