使用Linux提供的系統函數實現TCP通訊。
通訊步驟:
伺服器端:建立Socket->綁定到連接埠->開始監聽->等待->有用戶端串連->建立子進程(線程)開始通訊->繼續監聽。
用戶端 : 建立Socket->發起向伺服器的串連->串連成功->開始通訊->通訊結束,關閉Socket。
主要用到的函數:
socket,bind,listen,accept,send,recv,connect等。
已經通過測試的例子:
伺服器端 Server.cpp:
/***************************************在本機3333連接埠建立TCP監聽,有用戶端串連後向其先發送一段訊息,然後讀取用戶端的返回訊息。***************************************/#include <iostream>#include <string.h>//bzero()#include <stdio.h>//perror#include <stdlib.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>#include <netinet/in.h>/**ip addr struct **/#include <arpa/inet.h>using namespace std;int main(){ int sockfd,client_fd; int port=3333; struct sockaddr_in my_addr;/*本機地址資訊結構體*/ struct sockaddr_in rem_addr;//遠程客戶機地址資訊 if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("Socket error!");//建立socket出錯 exit(1); } else cout<<"socket success!"<< sockfd << endl; /*配置socket,IP和連接埠*/ my_addr.sin_family=AF_INET; my_addr.sin_port=htons(port);//伺服器監聽連接埠號碼host to net my_addr.sin_addr.s_addr=INADDR_ANY;//在本機任何IP(全部IP,多網卡的情況)接收資訊 bzero(&(my_addr.sin_zero),8);//置位元組字串s的前n個位元組為零。 if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1) { perror("bind error!"); exit(1); } else cout<<"bind success! "<<endl; if(listen(sockfd,10)==-1)///* 最大同時串連請求數 10*/ { perror("listen error!"); exit(1); } else cout<<"listening in port "<<port<<endl; while(1) { socklen_t sin_size = sizeof(struct sockaddr_in); cout<<"waiting for client..."<<endl; if((client_fd = accept(sockfd,(struct sockaddr*)&rem_addr,&sin_size))==-1) { perror("accept error!"); exit(1); } cout<<"received a connection from " <<inet_ntoa(rem_addr.sin_addr) <<endl; if(!fork())/*子進程代碼*/ { char st[]="Hello,you are connected." ; //if(write(client_fd,st,strlen(st))==-1),equal exp if(send(client_fd,st,strlen(st),0)==-1) { perror("send error!"); close(client_fd); exit(0); } else cout<<"sent successfully."<<endl; //receive info int revflag; char info[50]; bzero(info,49); revflag=recv(client_fd,info,49,0); string str(info); if(revflag==-1) cout<<" receive error"<<endl; else cout<<"Receive info : "<<str<<endl; close(client_fd); } } return 0;}
用戶端 Client.cpp:
/***********************************************向伺服器3333連接埠(本程式中使用本機迴路位址)發起TCP串連,串連成功後先向發送訊息,然後一直讀取伺服器發來的訊息***********************************************/#include <iostream>#include<stdio.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>//inet_addrusing namespace std;int main(){ int sockfd, serv_port=3333; struct sockaddr_in serv_addr; sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1) { perror("socket error"); exit(1); } serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(serv_port); serv_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//// bzero(&(serv_addr.sin_zero),8);//置位元組字串s的前n個位元組為零。 ////發起串連 int conres= connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)); if(conres==-1) { cerr<<"connect error!"<<endl; exit(1); } //then send info to server char st[]="Hello,I'm from Client t3!" ; if(send(sockfd,st,strlen(st),0)==-1) { perror("send error!"); close(sockfd); exit(0); } else cout<<"sent successfully."<<endl; int revflag=1; while(revflag!=-1) { char info[50]; bzero(info,49); revflag=recv(sockfd,info,49,0); string str(info); if(revflag==-1) cout<<" receive error"<<endl; else cout<<"Receive info : "<<str<<endl; } close(sockfd); return 0;}