题目一
完成基于TCP的客户端和服务器程序编写,要求服务器采用循环方式处理客户端的数据。
server.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/socket.h> #include <unistd.h> #include <errno.h> #include <arpa/inet.h> #define SERVER_PORT 5012 #define SERV_IP="127.0.0.1" int main(void) { int clientSocket = -1,listenSocket = -1; struct sockaddr_in cliaddr,seraddr; socklen_t clie_addr_len; char buf[BUFSIZ]; int n,i,ret; listenSocket = socket(AF_INET,SOCK_STREAM,0);//用来指定套接字使用的地址格式,通常使用AF_INET IPV4 //指定套接字的类型,若是SOCK_STREAM,则用的是tcp,指定使用的协议类型(当指定套接字类型后,可以设置为0,因为默认为UDP或TCP) if(-1 == listenSocket){ perror("socket error"); exit(1); } else { printf("listenSocket = %d\n",listenSocket); } // bzero(&seraddr,sizeof(seraddr)); seraddr.sin_family = AF_INET; seraddr.sin_port = htons(SERVER_PORT);//1024 ~ 49151:普通用户注册的端口号 seraddr.sin_addr.s_addr = htonl(INADDR_ANY); ret=bind(listenSocket,(struct sockaddr *)&seraddr,sizeof(seraddr));// 绑定这个套节字到一个本地地址 if(ret == -1){ perror("bind error"); exit(1); } listen(listenSocket,128);// 进入监听模式,监听队列中允许保持的尚未处理的最大连接数 if(ret == -1){ perror("listen error"); exit(1); } clie_addr_len = sizeof(cliaddr); clientSocket=accept(listenSocket,(struct sockaddr *)&cliaddr,&clie_addr_len);// 接受一个新连接,指向本地数据结构sockaddr_in的指针, //调用connect()的信息将存储在该结构中,返回一个socket 端口,用来通信 if(clientSocket == -1){ perror("accept error"); exit(1); } while(1){ n=read(clientSocket,buf,sizeof(buf));//收 for(i=0;i<n;i++) buf[i]=toupper(buf[i]); write(clientSocket,buf,n);//发 } close(clientSocket);// 关闭套节字 close(listenSocket); return 0; }
client.c
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #define SERVER_PORT 5012 #define SERV_IP="127.0.0.1" int main(void) { int clientSocket = -1; struct sockaddr_in seraddr; socklen_t serv_addr_len; char buf[BUFSIZ]; int n; clientSocket=socket(AF_INET,SOCK_STREAM,0); // 也可以在这里调用bind函数绑定一个本地地址, 否则系统将会自动安排 bzero(&seraddr,sizeof(seraddr)); seraddr.sin_family = AF_INET; seraddr.sin_port = htons(SERVER_PORT);// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址 // 如果你的计算机没有联网,直接使用127.0.0.1即可 seraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); connect(clientSocket,(struct sockaddr *)&seraddr,sizeof(seraddr)); while(1){ fgets(buf,sizeof(buf),stdin); write(clientSocket,buf,strlen(buf));// 向服务器端发送数据 n=read(clientSocket,buf,sizeof(buf));//从服务器端接收数据 write(1,buf,n); } close(clientSocket);// 关闭套节字 return 0; }
运行截图
题目二
完成基于UDP的客户端和服务器程序编写,要求服务器采用循环方式处理客户端的数据。
udpServer.c
#include<sys/types.h> #include<sys/socket.h> /*socket() bind()*/ #include<linux/in.h> /*struct sockaddr_in*/ #include<string.h> /*memset*/ #include<stdio.h> #include<stdlib.h> void udpserv_echo(int ,struct sockaddr*); int main(int argc,char *argv[]) { int s; struct sockaddr_in addr_ser,addr_clie; s = socket(AF_INET,SOCK_DGRAM,0);// 生成套接字文件描述符,用来指定套接字使用的地址格式,通常使用AF_INET IPV4 //指定套接字的类型,SOCK_STREAM数据报套接字,无连接,则用的是tcp,指定使用的协议类型(当指定套接字类型后,可以设置为0,因为默认为UDP或TCP); memset(&addr_ser,0,sizeof(addr_ser)); // 通过struct sockaddr_in 结构设置服务器地址和监听端口 addr_ser.sin_family = AF_INET; addr_ser.sin_addr.s_addr = htonl(INADDR_ANY);//把unsigned long类型从主机序转换到网络序 addr_ser.sin_port = htons(8888);//把unsigned short类型从主机序转换到网络序 bind(s,(struct sockaddr*)&addr_ser,sizeof(addr_ser)); udpserv_echo(s,(struct sockaddr*)&addr_clie); return 0; } void udpserv_echo(int s,struct sockaddr*addr_clie) { char buff[256]; int i=0; int n; char str[10]; socklen_t len; while(1) { len = sizeof(*addr_clie); sprintf(str,"%d",i);//把i转换为字符串 n=recvfrom(s,buff,256,0,addr_clie,&len);//收发数据,用函数send()和recv(),或者read()和write() strcat(buff,str);//把收到的数据+i再发送到客户端 printf("%s,%s\n",str,buff); sendto(s,buff,n+1,0,addr_clie,len); i++; } }
udpClient.c
#include<sys/types.h> #include<sys/socket.h> /*socket() bind()*/ #include<linux/in.h> /*struct sockaddr_in*/ #include<string.h> /*memset()*/ #include<stdio.h> void udpclie(int,struct sockaddr*); int main(int argc,char *argv[]) { int s; struct sockaddr_in addr_ser; s = socket(AF_INET,SOCK_DGRAM,0);//AF_INET IPV4协议,SOCK_DGRAM UDP协议 memset(&addr_ser,0,sizeof(addr_ser));//清空 addr_ser.sin_family = AF_INET;//IPV4 addr_ser.sin_addr.s_addr = htonl(INADDR_ANY);//将本地地址转换成无符号长整型的网络字节顺序。表示从本机的任一网卡接收数据 addr_ser.sin_port = htons(8888);//指定端口号把unsigned short类型从主机序转换到网络序 udpclie(s,(struct sockaddr*)&addr_ser); close(s); return 0; } void udpclie(int s,struct sockaddr*to) { char buff[256];// = "Hello udp"; struct sockaddr_in from; socklen_t len = sizeof(*to); while(1){ gets(buff);//puts(buff); sendto(s,buff,256,0,to,len);//收发数据,用函数send()和recv(),或者read()和write() recvfrom(s,buff,sizeof(buff),0,(struct sockaddr*)&from,&len); printf("recved:%s\n",buff); sleep(2); } }
作者:jiuqi_玖柒
原文链接:https://blog.csdn.net/qq_46036214/article/details/110501042#comments_14720027