大家好,欢迎来到IT知识分享网。
硬件:嵌入式开发板Tiny4412、PC 机、串口线、以太网连接线。
软件:PC 机操作系统 ubuntu14.04、minicom、arm-linux-gnueabi-gcc
一TCP 编程实验
流程图:
实验步骤:
1连接网线。
2配置MAC地址。
修改前的IP、MAC地址:
输入命令:
ifconfig eth0 down
ifconfig eth0 hw ether 1C:6F:65:34:51:71
ifconfig eth0 up
更改后的MAC地址:
3编写程序:
server.c
#include<netdb.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#define SOCK_PORT 9988
#define BUFFER_LENGTH 1024
#define MAX_CONN_LIMIT 512
static void Data_handle(void * sock_fd);
int main(int argc, char *argv[])
{
int sockfd_server;
int sockfd;
int fd_temp;
struct sockaddr_in s_addr_in;
struct sockaddr_in s_addr_client;
int client_length;
sockfd_server = socket(AF_INET,SOCK_STREAM,0); //创建socket
assert(sockfd_server != -1);
memset(&s_addr_in,0,sizeof(s_addr_in));
s_addr_in.sin_family = AF_INET;
s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr_in.sin_port = htons(SOCK_PORT);
fd_temp = bind(sockfd_server,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));//绑定地址信息
if(fd_temp == -1)
{
fprintf(stderr,"bind error!\n");
exit(1);
}
fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);//监听网络
if(fd_temp == -1)
{
fprintf(stderr,"listen error!\n");
exit(1);
}
while(1)
{
printf("waiting for new connection...\n");
pthread_t thread_id;
client_length = sizeof(s_addr_client);
sockfd = accept(sockfd_server,(struct sockaddr*)(&s_addr_client),(socklen_t *)(&client_length));//阻塞等待连接
if(sockfd == -1)
{
fprintf(stderr,"Accept error!\n");
continue;
}
printf("A new connection occurs!\n");
printf("client's IP is %s\n",inet_ntoa(s_addr_client.sin_addr));
if(pthread_create(&thread_id,NULL,(void *)(&Data_handle),(void *)(&sockfd)) == -1)//对每一个新的client创建新线程
{
fprintf(stderr,"pthread_create error!\n");
break;
}
}
int ret = shutdown(sockfd_server,SHUT_WR);
assert(ret != -1);
printf("Server shuts down\n");//关闭连接
return 0;
}
static void Data_handle(void * sock_fd)
{
int fd = *((int *)sock_fd);
int i_recvBytes;
char data_recv[BUFFER_LENGTH];
const char * data_send = "Server received the request successfully!";
while(1)
{
printf("waiting for request...\n");
memset(data_recv,0,BUFFER_LENGTH);
i_recvBytes = read(fd,data_recv,BUFFER_LENGTH);//从client接受消息
if(i_recvBytes == 0)
{
printf("Maybe the client has closed\n");
break;
}
if(i_recvBytes == -1)
{
fprintf(stderr,"read error!\n");
break;
}
if(strcmp(data_recv,"quit")==0)
{
printf("Quit command!\n");
break;
}
printf("read from client : %s\n",data_recv);//打印接收的消息
if(write(fd,data_send,strlen(data_send)) == -1)//发送给client回复信息
{
break;
}
}
printf("terminating current client_connection...\n");
close(fd);
pthread_exit(NULL); //退出线程
}
client.c
#include<netdb.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#define SOCK_PORT 9988
#define BUFFER_LENGTH 1024
int main(int argc, char *argv[])
{
int sockfd;
int tempfd;
struct sockaddr_in s_addr_in;
struct hostent *he;
char data_send[BUFFER_LENGTH];
char data_recv[BUFFER_LENGTH];
memset(data_send,0,BUFFER_LENGTH);
memset(data_recv,0,BUFFER_LENGTH);
if (argc != 2) {
fprintf( stderr,"usage: client hostname\n");
exit(1) ;
}
if ((he=gethostbyname(argv[1])) == NULL) {
perror("gethostbyname" ) ;
exit(1) ;
}
sockfd = socket(AF_INET,SOCK_STREAM,0); //创建socket对象
if(sockfd == -1)
{
fprintf(stderr,"socket error!\n");
exit(1);
}
memset(&s_addr_in,0,sizeof(s_addr_in));
s_addr_in.sin_addr = *((struct in_addr *)he->h_addr);
s_addr_in.sin_family = AF_INET;
s_addr_in.sin_port = htons(SOCK_PORT);
tempfd = connect(sockfd,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));//发起连接
if(tempfd == -1)
{
fprintf(stderr,"Connect error! \n");
exit(1);
}
while(1)
{
printf("input(\"quit\"):\n");
gets(data_send);
tempfd = write(sockfd,data_send,BUFFER_LENGTH);//向server发送数据
if(tempfd == -1)
{
fprintf(stderr,"write error\n");
exit(0);
}
if(strcmp(data_send,"quit") == 0) //等于quit退出
{
break;
}
else
{
tempfd = read(sockfd,data_recv,BUFFER_LENGTH);//从server读取数据
assert(tempfd != -1);
printf("%s\n",data_recv);
memset(data_send,0,BUFFER_LENGTH);
memset(data_recv,0,BUFFER_LENGTH);
}
}
int ret = shutdown(sockfd,SHUT_WR); //or you can use func close()--<unistd.h> to close the fd
assert(ret != -1);
return 0;
}
实验结果:
先在开发板上运行server,再在终端执行client
二UDP 编程实验
流程图:
实验步骤:
1配置MAC地址:
与TCP同样的步骤
2编写程序:
udp_client.c
#include<netdb.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#define SOCK_PORT 9988
#define BUFFER_LENGTH 1024
int main(int argc, char *argv[])
{
int sockfd;
int tempfd;
int len,addr_len;
struct sockaddr_in s_addr_in;
struct hostent *he;
char data_send[BUFFER_LENGTH];
char data_recv[BUFFER_LENGTH];
memset(data_send,0,BUFFER_LENGTH);
if (argc != 2) {
fprintf( stderr,"usage: client hostname\n");
exit(1) ;
}
if ((he=gethostbyname(argv[1])) == NULL) {
perror("gethostbyname" ) ;
exit(1) ;
}
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1)
{
fprintf(stderr,"socket error!\n");
exit(1);
}
memset(&s_addr_in,0,sizeof(s_addr_in));
s_addr_in.sin_addr = *((struct in_addr *)he->h_addr);
s_addr_in.sin_family = AF_INET;
s_addr_in.sin_port = htons(SOCK_PORT);
while(1)
{
printf("input(\"quit\"):\n");
gets(data_send);
addr_len=sizeof(s_addr_in);
len =sendto(sockfd, data_send , BUFFER_LENGTH,0, (struct sockaddr*)&s_addr_in, addr_len);//发送数据包
if(len <0)
{
perror("send");exit(0);
}
if(strcmp(data_send,"quit") == 0)
{
break;
}
}
int ret = shutdown(sockfd,SHUT_WR);
assert(ret != -1);
return 0;
}
udp_server.c
#include<netdb.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#define SOCK_PORT 9988
#define BUFFER_LENGTH 1024
static void Data_handle(void * sock_fd);
int main(int argc, char *argv[])
{
int sockfd_server;
int sockfd;
int fd_temp;
int len;
char buff[BUFFER_LENGTH];
struct sockaddr_in s_addr_in;
struct sockaddr_in s_addr_client;
int client_length;
sockfd_server = socket(AF_INET,SOCK_DGRAM,0);
assert(sockfd_server != -1);
memset(&s_addr_in,0,sizeof(s_addr_in));
s_addr_in.sin_family = AF_INET;
s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr_in.sin_port = htons(SOCK_PORT);
fd_temp = bind(sockfd_server,(struct sockaddr *)(&s_addr_in),sizeof(s_addr_in));//为自己绑定IP地址
if(fd_temp == -1)
{
fprintf(stderr,"bind error!\n");
exit(1);
}
while(1)
{
printf("waiting for new message\n");
pthread_t thread_id;
client_length = sizeof(s_addr_client);
len=recvfrom(sockfd_server, buff, BUFFER_LENGTH-1, 0, (struct sockaddr*)&s_addr_client, &client_length);//接收数据包
if(len <0)
{
perror("recv");
exit(0);
}
printf("client's IP is %s:%s\n",inet_ntoa(s_addr_client.sin_addr), buff);
}
int ret = shutdown(sockfd_server,SHUT_WR);
assert(ret != -1);
printf("Server shuts down\n");
return 0;
}
实验结果:
同样先运行udp_server
1.因为实验室开发板的MAC地址相同,所以在运行程序时要更改mac地址。
2.UDP 协议的每个发送和接收的数据报都包含了发送方和接收方的地址信息。在发送和接收数据之前,先要建立一个数据报方式的套接口,该socket 的类型为SOCK_ DGRAM,由于不需要建立连接,因此产生socket 后就可以直接发送和接收了。当然,要接收数据报也必须绑定一个端口,否则发送方无法得知要发送到哪个端口。sendto 和recvfrom 两个系统调用分别用于发送和接收数据报。
3.不绑定地址和端口的一方的地址和端口由内核分配。由于对方无法预先知道不绑定的一方的端口和IP 地址,因此只能由不绑定的一方先发出数据报,对方根据收到的数据报中的来源地址可以确定回送数据报所需要的发送地址。
4.我实现的UDPserver需要绑定地址和端口,并且通信只能由非绑定client方发起。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/33421.html









