tcp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#define N 32
#define ERRLOG(errmsg) do{\
perror("errmsg");\
printf("%s-%s-%d\n",__FILE__,__func__,__LINE__);\
exit(1);\
}while(0);
int main(int argc,const char *argv[])
{
if(argc<3)
{
fprintf(stderr,"Usage: %s <ip> <port>\n",argv[0]);
exit(1);
}
int sockfd,acceptfd;
struct sockaddr_in serveraddr,clientaddr;
socklen_t addrlen=sizeof(struct sockaddr_in);
//第一步,创建套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
ERRLOG("socket error");
}
//第二部,填充网络信息结构体
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
serveraddr.sin_port=htons(atoi(argv[2]));
//第三步,将套接字与服务器网络信息结构体绑定
if(bind(sockfd,(struct sockaddr *)&serveraddr,addrlen)==-1)
{
ERRLOG("bind error");
}
//第四步,将套接字设置为被动监听状态
if(listen(sockfd,5)==-1)
{
ERRLOG("listen error");
}
//第五步,阻塞等待客户端连接
if((acceptfd=accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen))==-1)
{
ERRLOG("accept error");
}
printf("客户端 %s:%d 已连接\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
char buf[32]={0};
ssize_t bytes;
pid_t pid;
//第六步,进行通信
if((pid=fork())==-1)
{
ERRLOG("fork error");
}
else if(pid>0)
{
while(1)
{
if((bytes=read(acceptfd,buf,N))==-1)
{
ERRLOG("read error");
}
else if(bytes==0)
{
printf("客户端 %s:%d 下线\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
exit(sockfd);
exit(acceptfd);
exit(0);
}
else
{
printf("client: %s\n",buf);
}
}
}
else
{
while(1)
{
memset(buf,0,N);
fgets(buf,N,stdin);
buf[strlen(buf)-1]='\0';
if(write(acceptfd,buf,N)==-1)
{
ERRLOG("write error");
}
}
}
return 0;
}
tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#define N 32
#define ERRLOG(errmsg) do{\
perror(errmsg);\
printf("%s-%s-%d\n",__FILE__,__func__,__LINE__);\
exit(1);\
}while(0);
int main(int argc,const char *argv[])
{
if(argc<3)
{
fprintf(stderr,"Usage: %s <ip> <port>\n",argv[0]);
exit(1);
}
int sockfd;
struct sockaddr_in serveraddr,clientaddr;
socklen_t addrlen=sizeof(struct sockaddr_in);
//第一步,创建套接字
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
ERRLOG("socket error");
}
//第二步,填充网络信息结构体
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);
serveraddr.sin_port=htons(atoi(argv[2]));
//第三步,向服务器发送连接请求
if(connect(sockfd,(struct sockaddr *)&serveraddr,addrlen)==-1)
{
ERRLOG("connect error");
}
char buf[N]={0};
ssize_t bytes;
pid_t pid;
//第四步,进行通信
if((pid=fork())==-1)
{
ERRLOG("fork error");
}
else if(pid>0)
{
while(1)
{
memset(buf,0,N);
fgets(buf,N,stdin);
buf[strlen(buf)-1]='\0';
if(write(sockfd,buf,N)==-1)
{
ERRLOG("write error");
}
}
}
else
{
while(1)
{
if((bytes=read(sockfd,buf,N))==-1)
{
ERRLOG("read error");
}
else if(bytes==0)
{
printf("服务器 %s:%s 关闭\n",argv[1],argv[2]);
close(sockfd);
exit(0);
}
else
{
printf("server: %s\n",buf);
}
}
}
return 0;
}