本实例详细注释网络编程TCP通信过程;
实例功能 客服器运行client.c程序,服务器返回时间。
实例运行过程:1 编译并运行sever.c程序;2 编译并运行client.c程序,如:./client 192.168.126.22,其中192.168.126.22为sever.c运行主机IP;3 client.c 显示时间,并关闭。
sever.c
#include<stdio.h> //perror
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<arpa/inet.h> //htons
#include<fcntl.h>
#include<netinet/in.h>
#include<sys/ioctl.h>
#include<time.h>
char buf[255];
int main()
{
//1 创建套接字
int socketfd;
int newfd;
socketfd = socket(AF_INET,SOCK_STREAM,0);
if(socketfd == -1)
{
perror("socket error");
return -1;
}
// 设置端口可以重复绑定 sockfd为需要端口复用的套接字
int opt = 1;
setsockopt(socketfd, SOL_SOCKET,SO_REUSEADDR,(const void *)&opt,sizeof(opt));
//2 绑定套接字
socklen_t addrlen = 0;
struct sockaddr_in local_addr; //地址结构体
bzero(&local_addr,sizeof(local_addr)); //清空local_addr
addrlen = sizeof(local_addr);
local_addr.sin_family = AF_INET; //地址族IPV4
local_addr.sin_port = htons(8888); //端口
local_addr.sin_addr.s_addr = htonl(INADDR_ANY); //IPV4 绑定所有IP
if(bind(socketfd,(struct sockaddr*)&local_addr,addrlen) == -1)
{
perror("bind error");
return -1;
}
//3 设置同时最大链接数
if(listen(socketfd,5) == -1)
{
perror("listen error");
return -1;
}
//4 等待连接
socklen_t len = 0;
struct sockaddr_in client_addr; //地址结构体
bzero(&client_addr,sizeof(client_addr));
len = sizeof(client_addr);
while(1)
{
newfd = accept(socketfd,(struct sockaddr*)&client_addr,&len); //连接
if(newfd < 0)
{
perror("accept error.");
return -1;
}
/*显示客服端信息*/
char buff[255] = {0};
const char *p = inet_ntop(AF_INET, &client_addr.sin_addr, buff, len);
//printf("p=%s\n", p);
printf("clientIP=%s\n", buff);
printf("port=%d\n", ntohs(client_addr.sin_port));
//时间
time_t timep;
time(&timep);
snprintf(buf, sizeof(buf), "%s", ctime(&timep));
printf("%s ",buf);
write(newfd,buf,strlen(buf)); //写入时间
}
}
2 client.c
#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<unistd.h>
#include<arpa/inet.h>
char buf[255];
int main(int argc,char** argv)
{
if (argc != 2)
{
printf("argv format errno,ap:./timeclient 192.168.1.1\n");
return -1;
}
//1 创建套接字
int socketfd;
socketfd = socket(AF_INET,SOCK_STREAM,0);
if(socketfd == -1)
{
perror("socket error");
return -1;
}
// 设置端口可以重复绑定 sockfd为需要端口复用的套接字
int opt = 1;
setsockopt(socketfd, SOL_SOCKET,SO_REUSEADDR,(const void *)&opt,sizeof(opt));
//2 连接
struct sockaddr_in saddr; //地址结构体
socklen_t len;
len = sizeof(saddr);
bzero(&saddr,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(8888);
saddr.sin_addr.s_addr = inet_addr(argv[1]); //外部传参
int ret = connect(socketfd,(struct sockaddr *)&saddr,len);
if(ret ==0) //成功
{
printf("connect sucess\n");
read(socketfd,buf,sizeof(buf)); //读出数据
printf("time = %s",buf);
}
else if(ret == -1)
{
printf("failed to connect\n");
return -1;
}
//3 关闭
close(socketfd);
}
3.运行
1.编译并运行sever程序
2.编译并运行client程序
注 192.168.116.129 为sever.c的IP
运行结果
sever端
client端