当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 6 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 本机之间数据通信
帖子发表于 : 2015-11-22 19:46 

注册: 2015-11-22 19:32
帖子: 4
系统: win7
送出感谢: 0 次
接收感谢: 0 次
本人菜鸟,初学学习Ubuntu遇到些问题,往路过的留意下帮我解决问题,谢谢!!!

学习网络编程与数据通信,在虚拟机中安装的Ubuntu,尝试在本机之间通信,接收和发送的函数都是教程里的,不知道为何我就是实现不了,出现连接失败的情况,不知道是否有哪些问题???

客户端函数如下
/* client.c : tcp */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h> /* 包含相关函数头文件 */
#include <sys/socket.h>
#define SERV_PORT 2369 /* 服务器监听端口号 */
#define SIZE 128 /* 缓冲区的长度 */
int main(int argc, char **argv)
{
int res;
int sockfd; /* 定义Socket描述符 */
struct sockaddr_in servaddr; /* 服务器IP地址和端口号信息 */
char buf[SIZE]; /* 定义缓冲区 */
int cnt;
if(argc != 2) /* 检查命令行参数个数是否正确 */
{
printf("参数错误。\n");
exit(1);
}
/* 创建套接字 */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1) /* 如果套接字创建失败,输出错误信息并退出 */
{
perror("套接字创建失败\n");
exit(1);
}
/* 向服务器发出连接请求 */
servaddr.sin_family = AF_INET; /* TCP/IP协议 */
servaddr.sin_port = htons(SERV_PORT); /* 服务器端口号,并转换为网络字节顺序 */
servaddr.sin_addr.s_addr = INADDR_ANY; /* 这里我们使用回环地址,即127.0.0.1 */
bzero(&(servaddr.sin_zero), 8); /* 清零 */
res = connect(sockfd, /* 建立连接 */
(struct sockaddr *)&servaddr, sizeof(struct sockaddr));
if(res == -1) /* 如果连接失败,输出错误信息并退出 */
{
perror("连接失败\n");
exit(1);
}
/* 发送数据 */
strcpy(buf, argv[1]);
cnt = send(sockfd, buf, SIZE, 0);
if(cnt == -1) /* 如果数据发送失败,输出错误信息并退出 */
{
perror("数据发送失败\n");
exit(1);
}
printf("发送数据: %s\n", buf); /* 输出所发送的字符串 */
close(sockfd); /* 关闭套接字 */
return 0;
}

服务端函数如下
/* server.c : tcp */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h> /* 包含相关函数头文件 */
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 2360 /* 服务器监听端口号 */
#define LENGTH 10 /* 请求队列的长度数 */
#define SIZE 128 /* 缓冲区的长度 */
int main()
{
int res;
int sockfd; /* 定义监听Socket描述符 */
int clientfd; /* 定义数据传输Socket描述符 */
struct sockaddr_in hostaddr; /* 本机IP地址和端口号信息 */
struct sockaddr_in clientaddr; /* 客户端IP地址和端口号信息 */
unsigned int addrlen;
char buf[SIZE]; /* 定义缓冲区 */
int cnt;
/* 创建套接字 */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd == -1) /* 如果套接字创建失败,输出错误信息并退出 */
{
perror("套接字创建失败\n");
exit(1);
}
/* 将套接字与IP地址和端口号进行绑定 */
hostaddr.sin_family = AF_INET; /* TCP/IP协议 */
hostaddr.sin_port = htons(SERV_PORT); /* 让系统随机选择一个未被占用的端口号 */
hostaddr.sin_addr.s_addr = INADDR_ANY; /* 本机IP地址 */
bzero(&(hostaddr.sin_zero), 8); /* 清零 */
res = bind(sockfd, (struct sockaddr *)&hostaddr, sizeof(struct sockaddr)); /* 绑定 */
if(res == -1) /* 如果套接字绑定失败,输出错误信息并退出 */
{
perror("套接字绑定失败\n");
exit(1);
}
/* 将套接字设为监听模式,以等待连接请求 */
res = listen(sockfd, LENGTH);
if(res == -1) {
perror("设置监听模式错误\n");
exit(1);
}
printf("等待客户端请求连接。\n ");
/* 请求到来后,接受连接请求,并接收数据 */
while(1)
{
addrlen = sizeof(struct sockaddr_in);
clientfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen); /* 接受连接请求 */
if(clientfd == -1)
{
perror("接受连接请求错误\n");
continue;
}
printf("客户端IP : %s\n", inet_ntoa(clientaddr.sin_addr)); /* 输出客户端IP地址 */
cnt = recv(clientfd, buf, SIZE, 0); /* 接收数据 */
if(cnt == -1) /* 如果数据接收失败,输出错误信息并退出 */
{
perror("数据接受失败\n");
exit(1);
}
printf("收到的数据 : %s\n", buf); /* 输出接收到数据 */
close(clientfd); /* 关闭数据传输套接字 */
}
return 0;
}

若能帮我解决问题,本人在此多谢了


页首
 用户资料  
 
2 楼 
 文章标题 : Re: 本机之间数据通信
帖子发表于 : 2015-11-23 12:07 
头像

注册: 2008-09-18 13:11
帖子: 2781
送出感谢: 1
接收感谢: 453
如果你的书上就是这么写的,那你可以直接把书扔了
1、服务端定义的SERV_PORT是2360,客户端定义的SERV_PORT是2369,这都连得上那才见鬼了
2、INADDR_ANY是0.0.0.0,回环地址127.0.0.1是INADDR_LOOPBACK。客户端是不能连INADDR_ANY的。而且要用htonl转换字节序


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 本机之间数据通信
帖子发表于 : 2015-11-25 20:07 

注册: 2015-11-22 19:32
帖子: 4
系统: win7
送出感谢: 0 次
接收感谢: 0 次
astolia 写道:
如果你的书上就是这么写的,那你可以直接把书扔了
1、服务端定义的SERV_PORT是2360,客户端定义的SERV_PORT是2369,这都连得上那才见鬼了
2、INADDR_ANY是0.0.0.0,回环地址127.0.0.1是INADDR_LOOPBACK。客户端是不能连INADDR_ANY的。而且要用htonl转换字节序

直接下载光盘的用的,没改过,确实定义得不对,客户端不能连INADDR_ANY要用转换,意思是转换之后才能连?


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 本机之间数据通信
帖子发表于 : 2015-11-25 20:13 

注册: 2015-11-22 19:32
帖子: 4
系统: win7
送出感谢: 0 次
接收感谢: 0 次
试过了,不行,
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
//servaddr.sin_addr.s_addr = INADDR_LOOPBACK;
这两句都分别试了下,还是一样的错误,参数错误,能说详细一点么


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 本机之间数据通信
帖子发表于 : 2015-11-26 11:23 
头像

注册: 2008-09-18 13:11
帖子: 2781
送出感谢: 1
接收感谢: 453
这种错误百出,连程序怎么用都不讲的书,也别心疼钱,直接和光盘一起扔了
INADDR_ANY是指绑定到本机所有接口,绝对不应该出现在connect的目标中。即使linux内核目前的实现将其是当作loopback,没有任何保证今后不会变,像你给的代码那样直接称作本地环回地址更是可笑。
任何对s_addr的赋值都应该经过htonl的处理,来保证字节序的正确。即使是INADDR_ANY这种转换后值一样的常量,初学者也应当养成先转换的好习惯。

最后,你觉得这段是什么意思?
引用:
if(argc != 2) /* 检查命令行参数个数是否正确 */
{
printf("参数错误。\n");
exit(1);
}


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 本机之间数据通信
帖子发表于 : 2015-11-26 19:19 

注册: 2015-11-22 19:32
帖子: 4
系统: win7
送出感谢: 0 次
接收感谢: 0 次
astolia 写道:
这种错误百出,连程序怎么用都不讲的书,也别心疼钱,直接和光盘一起扔了
INADDR_ANY是指绑定到本机所有接口,绝对不应该出现在connect的目标中。即使linux内核目前的实现将其是当作loopback,没有任何保证今后不会变,像你给的代码那样直接称作本地环回地址更是可笑。
任何对s_addr的赋值都应该经过htonl的处理,来保证字节序的正确。即使是INADDR_ANY这种转换后值一样的常量,初学者也应当养成先转换的好习惯。

最后,你觉得这段是什么意思?
引用:
if(argc != 2) /* 检查命令行参数个数是否正确 */
{
printf("参数错误。\n");
exit(1);
}

虽然不知道什么意思,但好像改回来,只改了服务器监听端口号,改成一样的就可以了,不过还是不知道为什么。。。。 :Adore


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 6 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译