linux下面TCP套接口编程 client/server实例


TCP十一个面向连接的网络协议,数据传输前必须先建立连接

即客户端和服务器之间需要有一个规则来相互约束。


两者之间的通信可以如下所示


1   建立socket套接口

2   bind函数 绑定端口和IP  

3  调用listen函数监听客户端发过来的请求

4 客户端建立socket套接口

5客户端用connect函数连接远程服务器ip端口

6服务器用accept函数接受客户端的请求,建立起通信连接

7建立起连接以后客户端可以用write函数(或者send函数)往socket服务器端发送数据,也可以用read函数(或者recv函数)读取客户端发送过来的数据

8服务器端可以用read函数(recv函数)读取客户端发送过来的数据,也可以用write函数(send函数)往客户端发送数据

9 通信完成以后用close关闭socket连接



服务器端程序如下所示:


<span style="font-size:18px;">#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAXSIZE 1024     /*定义数据缓冲区大小*/

int main(int argc, char *argv[])
{
int sockfd,new_fd;
struct sockaddr_in server_addr;   /*定义服务器端套接口数据结构server_addr */
struct sockaddr_in client_addr;   /*定义客户端套接口数据结构client_addr */
int sin_size,portnumber; 
char buf[MAXSIZE];     /*发送数据缓冲区*/
if(argc!=2)
{
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
if((portnumber=atoi(argv[1]))<0) 
{  /*获得命令行的第二个参数--端口号,atoi()把字符串转换成整型数*/
fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]);
exit(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
/*服务器端开始建立socket描述符*/
{
fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
exit(1);
} 
/*服务器端填充 sockaddr结构*/
bzero(&server_addr,sizeof(struct sockaddr_in)); /*先将套接口地址数据结构清零*/
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
                                   /*调用bind函数绑定端口*/
{ 
fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); 
exit(1); 
} 
if(listen(sockfd,5)==-1)  
/*端口绑定成功,监听sockfd描述符,同时处理的最大连接请求数为5 */
{
fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
exit(1);
}
while(1)      /*服务器阻塞,等待接收连接请求,直到客户程序发送连接请求*/
{
sin_size=sizeof(struct sockaddr_in);
if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1)
/*调用accept接受一个连接请求*/
{
fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); 
exit(1); 
}
fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
/*TCP连接已建立,打印申请连接的客户机的IP地址*/
printf("Connected successful, please input the masage[<1024 bytes]:\n");
        /*提示用户输入将要发送的数据,长度小于缓冲区的长度,即1024字节*/
if(fgets(buf, sizeof(buf), stdin) != buf)
{  /*从终端输入的数据存放在buf缓冲区*/
         printf("fgets error!\n");
         exit(1);
}
if(write(new_fd,buf,strlen(buf))==-1)   /*调用write发送数据*/
{
fprintf(stderr,"Write Error:%s\n",strerror(errno)); 
exit(1); 
} 
close(new_fd);  /*本次通信已结束,关闭客户端的套接口,并循环下一次等待*/
}
close(sockfd);  /*服务器进程结束,关闭服务器端套接口*/
exit(0);
}
</span>

客户端程序如下


<span style="font-size:18px;">#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

int main(int argc, char *argv[])
{
int sockfd;
char buffer[1024];
struct sockaddr_in server_addr; /*定义服务器端套接口数据结构server_addr */
struct hostent *host;
int portnumber,nbytes;
if(argc!=3)
{
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL)
{  /*获得命令行的第二个参数-主机名*/
fprintf(stderr,"Gethostname error\n");
exit(1);
}
if((portnumber=atoi(argv[2]))<0)
{  /*获得命令行的第三个参数--端口号,atoi()把字符串转换成整型数*/
fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
exit(1);
}
/* 客户程序开始建立 sockfd描述符 */
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
exit(1); 
} 
/*客户程序填充服务端的资料*/
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(portnumber);
server_addr.sin_addr=*((struct in_addr *)host->h_addr);
/*客户程序发起连接请求*/
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
{
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
exit(1);
}
/*连接成功,调用read读取服务器发送来的书籍*/
if((nbytes=read(sockfd,buffer,1024))==-1)
{
fprintf(stderr,"Read Error:%s\n",strerror(errno));
exit(1);
} 
buffer[nbytes]='\0';
printf("I have received:%s\n",buffer);   /*输出接收到的数据*/
close(sockfd);   /*结束通信*/ 
exit(0);
}
</span>

在终端编译链接程序

gcc -o server server.c

gcc -o cilent client.c


在一个终端下面输入   ./server 5678

在另一个终端中输入  ./cilent  localhost 5678

可以在服务器端看到一些提示


并且在服务器端输入一些  信息   I  like


然后在客户端可以收到服务器端输入的  I like 信息 


你可能感兴趣的:(linux,tcp,clientserver)