目录
- 代码
- 相互收发
- 文本交互
- 遇到的问题
代码
相互收发
server代码
/**********
1、在服务器端接受消息时知道对方的IP和端口提示:bind出现:Address already in use 方法:netstat -nap查看 用kill -9 pid杀死
2、利用TCP实现文件传输
**********/#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>#include<stdlib.h>//
#include<netinet/in.h>//int main(void)
{//建立套接字int server_fd=socket(AF_INET,SOCK_STREAM,0);if(server_fd==-1){perror("socket:");return -1;}//设置套接字可以使用本机ip端口,否则ip只能用127.0.0.0int on_soc = 1;if(setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR,&on_soc,sizeof(on_soc))<0){perror("fial to setsockopt");exit(1);}//绑定本机的IP和端口struct sockaddr_in saddr;saddr.sin_family=AF_INET;saddr.sin_port=htons(8888); //设置端口saddr.sin_addr.s_addr=inet_addr("192.168.31.109"); //点分十进制-》换成32位的网络字节序二进制值int ret=bind(server_fd,(struct sockaddr *)&saddr,sizeof(saddr));if(ret==-1){perror("bind:");return -1;}//设置监听套接字(设置同时来链接数)ret=listen(server_fd,4); //server_fd设置为监听套接字if(ret==-1){perror("listen:");return -1;}//等待对端链接struct sockaddr_in client_buf;socklen_t len = sizeof(client_buf);int client_fd = accept(server_fd,(struct sockaddr *)&client_buf,&len); //成功返回对端的文件描述符if(-1 == client_fd){perror("accept:");return -1;}//显示对端的ip和端口printf("对端的ip为:%s\n",inet_ntoa(client_buf.sin_addr));printf("对端的port为:%d\n",ntohs(client_buf.sin_port));while(1){//接收数据char buffer1[20];memset(buffer1,0,sizeof(buffer1));// int len_rec = recv(client_fd,buffer1,sizeof(buffer1),0);int len_rec = read(client_fd,buffer1,sizeof(buffer1));if(len_rec > 0){printf("客户端发来消息: %s\n",buffer1);write(client_fd,buffer1,sizeof(buffer1));}if(len_rec == 0){printf("连接断开\n");break;}if(len_rec < 0){perror("faile to read \n");break;}}
/*********************** //文件操作int fd=open("b.txt",O_RDWR | O_CREAT,0777);if(-1 == fd){printf("open err!\n");return -1;}char buf[20] = {0};while(1){//第一题// bzero(buf, 20);// read(client_fd, buf, 20);// printf("buf:%s\n", buf);//第二题bzero(buf, 20);read(client_fd, buf, 20);printf("buf:%s\n", buf);if(!strcmp(buf, "exit"))break;write(fd,buf,strlen(buf));}
*********************/close(client_fd);close(server_fd);
}
client代码
/**********
1、在服务器端接受消息时知道对方的IP和端口提示:bind出现:Address already in use 方法:netstat -nap查看 用kill -9 pid杀死
2、利用TCP实现文件传输
**********/#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#include<stdlib.h>//
#include<netinet/in.h>//#include<errno.h>
int main(void)
{//建立套接字int client_fd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == client_fd){perror("socket");return -1;}//链接服务器struct sockaddr_in saddr;bzero(&saddr, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(8888);saddr.sin_addr.s_addr = inet_addr("192.168.31.109");int ret = connect(client_fd, (struct sockaddr *)&saddr, sizeof(saddr));if(-1 == ret){perror("connect");return -1;}int number =1;while(1){//发送数据char buffer1[20];sprintf(buffer1,"hi: %d",number++);send(client_fd,buffer1,strlen(buffer1)+1,0);//接收数据memset(buffer1,0,20);int len_rec = recv(client_fd,buffer1,sizeof(buffer1),0);if(len_rec > 0){printf("接收到服务器:%s\n",buffer1);}if(len_rec == 0){printf("连接断开\n");break;} if(len_rec < 0){perror("faile to read \n");break;}sleep(1);}/***//文件操作int fd=open("a.txt",O_RDWR | O_CREAT,0777);if(-1 == fd){printf("open err!\n");return -1;}char fd_buf[20]={0};while(1){bzero(fd_buf,20);ret = read(fd, fd_buf, 20); //读文件到缓冲区if(ret==0){write(client_fd,"exit", 20);break;}else{printf("fd_buf%s\n",fd_buf);write(client_fd, fd_buf, 20);}**/ /*bzero(fd_buf, 20);scanf("%s", fd_buf);write(client_fd, fd_buf, 20);printf("fd_buf:%s\n", fd_buf);if(!strcmp(fd_buf, "exit"))break;*///}close(client_fd);}
文本交互
server代码
/**********
1、在服务器端接受消息时知道对方的IP和端口提示:bind出现:Address already in use 方法:netstat -nap查看 用kill -9 pid杀死Server端bind本机IP地址使用INADDR_ANY
2、利用TCP实现文件传输
**********/#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>int main(void)
{//建立套接字int server_fd=socket(AF_INET,SOCK_STREAM,0);if(server_fd==-1){perror("socket:");return -1;}//绑定本机的IP和端口struct sockaddr_in saddr;saddr.sin_family=AF_INET;saddr.sin_port=htons(7777); //设置端口saddr.sin_addr.s_addr=inet_addr("192.168.31.109"); //点分十进制-》换成32位的网络字节序二进制值//这里的ip是服务端本机的ipint ret=bind(server_fd,(struct sockaddr *)&saddr,sizeof(saddr));if(ret==-1){perror("bind:");return -1;}//设置监听套接字(设置同时来链接数)ret=listen(server_fd,4); //server_fd设置为监听套接字if(ret==-1){perror("listen:");return -1;}//等待对端链接struct sockaddr_in client_buf;socklen_t len = sizeof(client_buf);int client_fd = accept(server_fd,(struct sockaddr *)&client_buf,&len); //成功返回对端的文件描述符if(-1 == client_fd){perror("accept:");return -1;}//显示对端的ip和端口printf("对端的ip为:%s\n",inet_ntoa(client_buf.sin_addr));printf("对端的port为:%d\n",ntohs(client_buf.sin_port));//文件操作int fd=open("b.txt",O_RDWR | O_CREAT,0777);if(-1 == fd){printf("open err!\n");return -1;}char buf[20] = {0};while(1){//第一题/*bzero(buf, 20);read(client_fd, buf, 20);printf("buf:%s\n", buf);*///第二题bzero(buf, 20);read(client_fd, buf, 20);printf("buf:%s\n", buf);if(!strcmp(buf, "exit"))break;write(fd,buf,strlen(buf));}close(client_fd);close(server_fd);
}
client代码
/**********
1、在服务器端接受消息时知道对方的IP和端口提示:bind出现:Address already in use 方法:netstat -nap查看 用kill -9 pid杀死
2、利用TCP实现文件传输
**********/#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(void)
{//建立套接字int client_fd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == client_fd){perror("socket");return -1;}//链接服务器struct sockaddr_in saddr;bzero(&saddr, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(7777);saddr.sin_addr.s_addr = inet_addr("192.168.31.109");int ret = connect(client_fd, (struct sockaddr *)&saddr, sizeof(saddr));if(-1 == ret){perror("connect");return -1;}//文件操作int fd=open("a.txt",O_RDWR | O_CREAT,0777);if(-1 == fd){printf("open err!\n");return -1;}char fd_buf[20]={0};while(1){bzero(fd_buf,20);ret = read(fd, fd_buf, 20); //读文件到缓冲区if(ret==0){write(client_fd,"exit", 20);break;}else{printf("fd_buf%s\n",fd_buf);write(client_fd, fd_buf, 20);}/*bzero(fd_buf, 20);scanf("%s", fd_buf);write(client_fd, fd_buf, 20);printf("fd_buf:%s\n", fd_buf);if(!strcmp(fd_buf, "exit"))break;*/}close(client_fd);}
遇到的问题
1.Connection refused: connect服务端没有开启
2.gcc指令使用错误示范:gcc -c server.c -o server.out
,加-c
是不对的。
3.bind函数出现Cannot assign requested address
方法一:通过netstat -nap查看当前的状态,的确看到很多TIME_WAIT状态的连接。可以通过pid 用命令 kill -9 pid,杀死处于TIME_WAIT状态的进程。问题二:因为我的测试是以window当服务器,Ubuntu当客户端,所以需要用到桥接技术,让两个系统在一个网段里面。那么出现bind的错误很有可能是你的网络的问题。我自己在测试的时候,试了很多种方法,还能ping通,但是网络这一块还是有点问题,还是出现bind错误。
import socket
#创建服务端的socket对象socketserver
socketserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.31.24"
port = 8000
#绑定地址(包括ip地址会端口号)
socketserver.bind((host, port))
#设置监听
socketserver.listen(5)
#等待客户端的连接
#注意:accept()函数会返回一个元组
#元素1为客户端的socket对象,元素2为客户端的地址(ip地址,端口号)
clientsocket,addr = socketserver.accept()#while循环是为了能让对话一直进行,直到客户端输入q
while True:#接收客户端的请求recvmsg = clientsocket.recv(1024)#把接收到的数据进行解码strData = recvmsg.decode("utf-8")#判断客户端是否发送q,是就退出此次对话if strData=='q':breakprint("收到:"+strData)msg = input("回复:")#对要发送的数据进行编码clientsocket.send(msg.encode("utf-8"))
import socket
#创建一个客户端的socket对象
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#设置服务端的ip地址
host = "192.168.31.24"
#设置端口
port = 8000
#连接服务端
client.connect((host, port))#while循环是为了保证能持续进行对话
while True:#输入发送的消息sendmsg = input("请输入:")#如果客户端输入的是q,则停止对话并且退出程序if sendmsg=='q':breaksendmsg = sendmsg#发送数据,以二进制的形式发送数据,所以需要进行编码client.send(sendmsg.encode("utf-8"))msg = client.recv(1024)#接收服务端返回的数据,需要解码print(msg.decode("utf-8"))
#关闭客户端
client.close()
4.Cannot assign requested address解决办法
链接: Cannot assign requested address