注意:服务器中的ip(192.168.31.122)和端口号port(6666)客户端中必须一致
编译:客户端:gcc tcp_client.c -o client
服务器:gcc tcp_server.c -o server
运行:客户端:./client
服务器:./server 192.168.31.122 6666
客户端:
tcp_client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#define SIZE 64
int main(int argc, char *argv[])
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建网络通信接口
if(-1 == sockfd)
{
perror("socket");
return -1;
}
printf("sockfd=%d\n",sockfd);
struct sockaddr_in saddr;//服务器的地址结构
bzero(&saddr,sizeof(saddr));//memset()
saddr.sin_family = AF_INET;//指定协议族ipv4
saddr.sin_port = htons(6666);//端口号:5001~65535
saddr.sin_addr.s_addr = inet_addr("192.168.31.122");//ip地址 点分式 -> 二进制网络字节序
int ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));//绑定 将服务器的ip和port与sockfd绑定
if(-1 == ret)
{
perror("connect");
close(sockfd);
return -1;
}
printf("connect success\n");
//通信
char buf[SIZE] = {0};
do{
fgets(buf,sizeof(buf),stdin);//标准输入获取字符串
ret = write(sockfd,buf,sizeof(buf));//给服务器写请求
if(-1 == ret)
{
perror("write");
break;
}
bzero(buf,sizeof(buf));
ret = read(sockfd, buf, sizeof(buf));//读取服务器回传的内容
if(-1 == ret)
{
perror("read");
break;
}
printf("buf:%s\n",buf);
}
while(strncmp(buf,"quit",4) != 0);
printf("ret=%d\n",ret);
close(sockfd);
return 0;
}
服务器
tcp_server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE 64
int server_init(char *ipaddr, unsigned short port, int backlog)
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);//创建网络通信接口
if(-1 == sockfd)
{
perror("socket");
return -1;
}
//printf("sockfd=%d\n",sockfd);
struct sockaddr_in saddr;//服务器的地址结构
bzero(&saddr,sizeof(saddr));//memset()
saddr.sin_family = AF_INET;//指定协议族ipv4
saddr.sin_port = htons(port);//端口号:5001~65535
saddr.sin_addr.s_addr = (ipaddr == NULL)? htonl(INADDR_ANY) : inet_addr(ipaddr);//ip地址 点分式 -> 二进制网络字节序
int ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));//绑定 将服务器的ip和port与sockfd绑定
if(-1 == ret)
{
perror("bind");
close(sockfd);
return -1;
}
//printf("bind success\n");
ret = listen(sockfd, backlog);//监听是否有客户端请求连接 sockfd:监听套接字
if(-1 == ret)
{
perror("listen");
close(sockfd);
return -1;
}
return sockfd;
}
int main(int argc, char *argv[])
{
if(argc < 3)
{
printf("Usage:%s <ip> <port>\n",argv[0]);
return -1;
}
int sockfd = server_init(argv[1], atoi(argv[2]), 1024);
if(-1 == sockfd)
{
printf("server_init error\n");
return -1;
}
printf("listen....\n");
struct sockaddr_in caddr;//保存客户端的信息(ip port protocol)
bzero(&caddr, sizeof(caddr));
socklen_t clen = sizeof(caddr);
//rws:用于服务器和连接的客户端通信
int rws = accept(sockfd, NULL, NULL);//阻塞等待客户端请求连接
if(-1 == rws)
{
perror("accept");
close(sockfd);
return -1;
}
printf("rws=%d\n",rws);
//通信
char buf[SIZE] = {0};
do{
bzero(buf, sizeof(buf));
int ret = recv(rws,buf,sizeof(buf),0);//读客户端消息
if(-1 == ret)
{
perror("recv");
break;
}
else if(0 == ret)//表示客户端关闭
{
printf("client closed\n");
return -1;
}
//回传消息给客户端
ret = send(rws,buf,sizeof(buf),0);
if(-1 == ret)
{
perror("send");
break;
}
}
while(strncmp(buf,"quit",4)!=0);
if(-1 == close(rws))
{
}
close(sockfd);
return 0;
}
运行结果: