提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
一、tcp通讯的链接
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。
二、使用步骤
1.引入库
代码如下(示例):
服务器端
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("please input %s <port>\n", argv[0]);
return -1;
}
int sockfd, acceptfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket err.");
return -1;
}
struct sockaddr_in serveraddr, caddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[1]));
// serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
//自动获取ip
//serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
// serveraddr.sin_addr.s_addr=INADDR_ANY; //0.0.0.0
serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
socklen_t len = sizeof(caddr);
if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("bind err.");
return -1;
}
if (listen(sockfd, 5) < 0)
{
perror("listen err.");
return -1;
}
while (1)
{
acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
if (acceptfd < 0)
{
perror("accept err.");
return -1;
}
printf("client:ip=%s port=%d\n",
inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port));
char buf[128];
pid_t pid = fork();
if (pid < 0)
{
perror("fork err.");
return -1;
}
else if (pid == 0) //发送
{
int sendbyte;
while (1)
{
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
sendbyte = send(acceptfd, buf, sizeof(buf), 0);
if (sendbyte < 0)
{
perror("send error.");
return -1;
}
}
}
else
{
int recvbyte;
while (1)
{
recvbyte = recv(acceptfd, buf, sizeof(buf), 0);
if (recvbyte < 0)
{
perror("recv err.");
return -1;
}
else if (recvbyte == 0)
{
printf("client exit.\n");
kill(pid,SIGKILL);
wait(NULL);
break;
}
else
{
printf("buf:%s\n", buf);
}
}
close(acceptfd);
}
}
close(sockfd);
return 0;
}
2.读入数据
代码如下(示例):
客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(int argc, char const *argv[])
{
if (argc != 3)
{
printf("please input %s <ip> <port>\n", argv[0]);
return -1;
}
//1.创建套接子
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
perror("socket error.");
return -1;
}
printf("sockfd=%d\n", sockfd);
//填充ipv4的通信结构体 服务器的ip和端口
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(atoi(argv[2]));
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
//2.请求链接服务器
if (connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("connect error.");
return -1;
}
//5.循环发送消息 通信
char buf[128];
pid_t pid = fork();
if (pid < 0)
{
perror("fork err.");
return -1;
}
else if (pid == 0)
{
int recvbyte;
while (1)
{
recvbyte = recv(sockfd, buf, sizeof(buf), 0);
if (recvbyte < 0)
{
perror("recv err.");
return -1;
}
printf("buf:%s\n", buf);
}
}
else
{
int sendbyte;
while (1)
{
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
sendbyte = send(sockfd, buf, sizeof(buf), 0);
if (sendbyte < 0)
{
perror("send error.");
return -1;
}
if(strncmp(buf,"quit",4)==0)
{
kill(pid,SIGKILL);
wait(NULL);
exit(-1);
}
}
}
close(sockfd);
return 0;
}
注意
tcp协议要统一端口号,才能实现通信。
如果服务器端的ip地址不是自动获取则需要填写手动填写正确可用的ip