1、TCP客户端:
客户端的初始化:
1、创建套接字
2、保存服务器的IP+端口号
3、发起连接请求
客户端处理业务:
4、通信
客户端业务办理结束:
5、关闭套接字
2、TCP服务器:
服务器初始化:
1、创建套接字
2、绑定自己的IP+端口
3、创建监听队列
4、等待建立连接
服务器通信:
5、通信
服务器办理新客户单业务结束:
6、关闭创建的与新客户端通信的套接字
3、代码展示:
3-1、client.c
#include "net.h"
int client_initial_func(const char *IP, const char *Port)
{
//创建套接字
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
perror("socket error");
return SOCK_ERROR;
}
printf("socket ok!\n");
//定义地址信息结构,存储服务器的IP地址和端口号
struct sockaddr_in serverAddr;
//清空
memset(&serverAddr, '\0', sizeof(serverAddr));
//赋值
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons((short)atoi(Port));
serverAddr.sin_addr.s_addr = inet_addr(IP);
//发起连接请求
int ret = connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if(ret < 0)
{
perror("connect error");
return CONNECT_ERROR;
}
printf("connect ok!\n");
return sockfd;
}
int client_com_func(int sockfd)
{
pid_t pid=0;
pid=fork();
if(pid<0)
{
perror("fork error");
return FORK_ERROR;
}
else if(pid==0)
{
//往服务器发送数据
char Message[100] = {0};
printf("客户端请输入消息:\n");
fgets(Message, sizeof(Message), stdin);//从键盘获取数据到Mesaage
//单独判断Message内容是否为quit
if(0 == strncasecmp("quit", Message, 4))//QUIT Quit quit
{
return QUIT;
}
int count = send(sockfd, Message, strlen(Message), 0);
if(count < 0)
{
perror("send error");
return SEND_ERROR;
}
else if(0 == count)
{
printf("未发送任何消息!\n");
return QUIT;
}
else
{
printf("send to server ok!\n");
}
}
else if(pid>0)
{
//接收服务端发送的数据
char Message[100] = {0};
int count = recv(sockfd, Message, sizeof(Message), 0);
if(count < 0)
{
perror("recv error");
return RECV_ERROR;
}
else if(0 == count)
{
printf("服务端已退出!\n");
return QUIT;
}
else
{
printf("服务端:%s\n",Message);
}
}
return OK;
}
int main(int argc, const char *argv[])
{
if(argc<3)
{
return NUM_ERROR;
}
//搭建TCP客户端
//客户端端初始化
int sockfd = client_initial_func(argv[1], argv[2]);
if(sockfd < 0)
{
return ERROR;
}
printf("client_initial success!\n");
//通信
while(1)
{
if(client_com_func(sockfd) < 0)
{
break;
}
}
//关闭套接字
close(sockfd);
return 0;
}
3-2、server.c
#include "net.h"
int server_initial_func(const char *IP,const char *Port)
{
//创建套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("socket error");
return SOCK_ERROR;
}
printf("socket ok!\n");
//定义地址信息结构,存储服务器的IP地址和端口号
struct sockaddr_in serverAddr;
//清空
memset(&serverAddr, '\0', sizeof(serverAddr));
//赋值
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons((short)atoi(Port));
serverAddr.sin_addr.s_addr = inet_addr(IP);
//绑定IP地址和端口
if(bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
{
perror("bind error");
return BIND_ERROR;
}
printf("bind IP+Port ok!\n");
//创建监听队列
if(listen(sockfd, 5) < 0)
{
perror("listen error");
return LISTEN_ERROR;
}
printf("listening......\n");
return sockfd;
}
int server_com_func(int newfd)
{
pid_t pid=0;
pid=fork();
if(pid<0)
{
perror("fork error");
return FORK_ERROR;
}
else if(pid==0)
{
//接收客户端发送的数据
char Message[100] = {0};
int count = recv(newfd, Message, sizeof(Message), 0);
if(count < 0)
{
perror("recv error");
return RECV_ERROR;
}
else if(0 == count)
{
printf("客户端已退出!\n");
return QUIT;
}
else
{
printf("客户端:%s\n",Message);
}
}
else if(pid>0)
{
//往客户端发送数据
char Message[100] = {0};
printf("服务器端请输入消息:\n");
fgets(Message, sizeof(Message), stdin);//从键盘获取数据到Mesaage
//单独判断Message内容是否为quit
if(0 == strncasecmp("quit", Message, 4))//QUIT Quit quit
{
return QUIT;
}
int count = send(newfd, Message, strlen(Message), 0);
if(count < 0)
{
perror("send error");
return SEND_ERROR;
}
else if(0 == count)
{
printf("未发送任何消息!\n");
return QUIT;
}
else
{
printf("send to server ok!\n");
}
}
return OK;
}
int main(int argc, const char *argv[])
{
if(argc<3)
{
return NUM_ERROR;
}
//搭建TCP服务器
//服务器端初始化
int sockfd = server_initial_func(argv[1], argv[2]);
if(sockfd < 0)
{
return ERROR;
}
printf("server_initial success!\n");
//等待建立连接(本质:获取连接成功的客户端对应的通信套接字,从内核中)
int newfd = accept(sockfd, NULL, NULL);
if(newfd < 0){
perror("accept error");
return ACCEPT_ERROR;
}
printf("accept ok!\n");
//通信
while(1)
{
if(server_com_func(newfd) < 0)
{
break;
}
}
//关闭套接字
close(sockfd);
close(newfd);
return 0;
}
3-3、net.h
#ifndef _NET_H_
#define _NET_H_
//定义枚举,表示返回值
enum VALUE_RET
{
FORK_ERROR=-11,
NUM_ERROR=-10,
QUIT = -9,
SOCK_ERROR = -8,
BIND_ERROR,
LISTEN_ERROR,
ACCEPT_ERROR,
SEND_ERROR,
RECV_ERROR,
CONNECT_ERROR,
ERROR,
OK
};
//添加所需的头文件以及函数声明
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int server_initial_func(const char *IP, const char *Port);
int client_initial_func(const char *IP, const char *Port);
int server_com_func(int newfd);
int client_com_func(int sockfd);
#endif
该代码实现了实现客户端和服务器均可发送以及接收消息
如图所示: