实验目的
- 了解TCP的原理
- 了解C/S框架
- 掌握TCP C/S框架的实现
实验内容
- 实现TCP服务器(server)
- 实现TCP客户端(client)
- 熟练使用socket函数创建套接字
- 使用ifconfig查看对应IP
实验原理
- 服务器端(server)
- 创建套接字 socket( )
- 填充服务器网络信息结构体 sockaddr_in
- 将套接字与服务器网络信息结构体绑定 bind( )
- 将套接字设置为被动监听状态 listen( )
- 阻塞等待客户端的连接请求 accept( )
- 进行通信 recv( )/send( )
- 客户端(client)
- 创建套接字 socket( )
- 填充服务器网络信息结构体 sockaddr_in
- 发送客户端的连接请求 connect( )
- 进行通信 send( )/recv( )
程序设计
服务器端(server):
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"unistd.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"arpa/inet.h"
#define PORT 33333
int main()
{
int sockfd;
int cfd;
int c_len;
char buffer[1024];
struct sockaddr_in addr;
struct sockaddr_in c_addr;
sockfd = socket(AF_INET, SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("socket create error!");
exit(1);
}
printf("socket success\n");
int opt = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family =AF_INET;
addr.sin_port =htons(PORT);
addr.sin_addr.s_addr = inet_addr("192.168.182.128");//ip各人不一样啊,ifconfig查一下
if(bind(sockfd,(struct sockaddr *)(&addr),sizeof(struct sockaddr_in)) <0)
{
perror("bind error!");
exit(1);
}
printf("bind success\n");
if(listen(sockfd,3)<0)
{
perror("listen error!");
exit(1);
}
printf("listen success\n");
while(1)
{
memset(buffer,0,sizeof(buffer));
bzero(&c_addr,sizeof(struct sockaddr_in));
c_len = sizeof(struct sockaddr_in);
printf("accept.......\n");
cfd = accept (sockfd,(struct sockaddr *)(&c_addr),&c_len);
if(cfd<0)
{
perror("accept error!");
exit(1);
}
printf("port =%d ip =%s\n",ntohs(c_addr.sin_port),inet_ntoa(c_addr.sin_addr));
//read(cfd,buffer,sizeof(buffer));
recv(cfd,buffer,sizeof(buffer),0);
printf("recv = %s\n",buffer);
usleep(2);
//write(cfd,buffer,strlen(buffer));
send(cfd,buffer,sizeof(buffer),0);
close(cfd);
}
return 0;
}
客户端(client):
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"unistd.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"arpa/inet.h"
#define PORT 33333
int main()
{
int sockfd;
struct sockaddr_in s_addr;
if((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("socket error");
exit(1);
}
printf("client socket success!\n");
bzero(&s_addr,sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr=inet_addr("192.168.182.128");//ifconfig查一下
if(connect(sockfd,(struct sockaddr *)(&s_addr),sizeof(struct sockaddr_in))<0)
{
perror("connect error!");
exit(1);
}
printf("connect success!\n");
write(sockfd,"hello world",12);
char buffer[1024];
read(sockfd,buffer,sizeof(buffer));
printf("recv server =%s\n",buffer);
return 0;
}
运行结果
root@jsetc-virtual-machine:/0504# ./c
client socket success!
connect success!
recv server =hello world
root@jsetc-virtual-machine:/0504# ./c
client socket success!
connect success!
recv server =hello world
root@jsetc-virtual-machine:/0504# ./s
socket success
bind success
listen success
accept.......
port =37928 ip =192.168.182.128
recv = hello world
accept.......
port =37930 ip =192.168.182.128
recv = hello world
accept.......
^C
实验总结
实验中的客户端与服务器基本实现了一方写一方读,绑定IP的时候一定记得用自己的IP。