使用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_addr
using 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;
}