socket初学者 数据多次发送接收问题,请高手帮忙。多谢了

yayayo780503 2012-04-06 06:10:30
代码功能说明:
为了研究下send,recv的同步关系,写了一段代码如下。
connect后,client在 while里send 1,2,3,4,5 5个data, server端在while里读取。

报错:
client端
while start
str= 0,len=1
str= 1,len=1
send出错!: Connection reset by peer

server端
读第一个时就直接报错:“recv出错!: Transport endpoint is not connected”。请高手帮忙解疑释惑。

下面是代码:
//client的
#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */

//return the length of result string. support only 10 radix for easy use and better performance
int my_itoa(int val, char* buf)
{
const unsigned int radix = 10;

char* p;
unsigned int a; //every digit
int len;
char* b; //start of the digit char
char temp;
unsigned int u;

p = buf;

if (val < 0)
{
*p++ = '-';
val = 0 - val;
}
u = (unsigned int)val;

b = p;

do
{
a = u % radix;
u /= radix;

*p++ = a + '0';

} while (u > 0);

len = (int)(p - buf);

*p-- = 0;

//swap
do
{
temp = *p;
*p = *b;
*b = temp;
--p;
++b;

} while (b < p);

return len;
}

main(int argc, char *argv[]){
int sockfd, recvbytes;
char buf[MAXDATASIZE] = {0};
struct hostent *host;
struct sockaddr_in serv_addr;
int i=0;
if (argc < 2) {
fprintf(stderr,"Please enter the server's hostname! ");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL) {
herror("gethostbyname出错!");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket创建出错!");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sockfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) == -1) {
perror("connect出错!");
exit(1);
}

/* if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) {
perror("recv出错!");
exit(1);
}
buf[recvbytes] = "\0";
printf("Received: %s,recvbytes=%d ",buf,recvbytes);
*/

//printf("cmd is %s, length =%d",argv[2],strlen(argv[2]));
printf("while start \n");
while(i<5)
{
char str[10];
int len;
memset(str,0,10);
len = my_itoa(i,str);
printf("str= %s,len=%d \n",str,len);
if (send(sockfd, str,len+1, 0) == -1)
perror("send出错!");
i++;
sleep(1);
}

printf("while end \n");
close(sockfd);
}

//server端的代码
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */

#define MAXDATASIZE 100
void main()
{
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
struct sockaddr_in my_addr; /* 本机地址信息 */
struct sockaddr_in remote_addr; /* 客户端地址信息 */
int sin_size;
int recvbytes;
char buf[MAXDATASIZE] = {0};

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket创建出错!"); exit(1);
}

my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind出错!");
exit(1);
}

if (listen(sockfd, BACKLOG) == -1) {
perror("listen出错!");
exit(1);
}
//accept
sin_size = sizeof(struct sockaddr_in);
if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) {
perror("accept出错");

}
//printf("received a connection from %s ", inet_ntoa(remote_addr.sin_addr));
printf("received a connection from\n");

while(1) {


//recv
memset(buf,0,MAXDATASIZE);
if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) {
perror("recv出错!");
//exit(1);
}

if(recvbytes > 0) // there is data
{

printf("Received: %s,recvbytes=%d \n",buf,recvbytes);
//do something

}

}
}

...全文
230 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
景语 2012-04-26
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

自己来结下贴:
但只能运行一个send,没有继续发送。
===》
设置了keepalive属性。使得建立的链接一直保持着就可以了。
语句如下:
if ( setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &flag, len) == -1 ) {

perror("setsockopt");

……
[/Quote]

不用设置这个属性也能持续收发
除非你中途调用了close()函数
yayayo780503 2012-04-26
  • 打赏
  • 举报
回复
自己来结下贴:
但只能运行一个send,没有继续发送。
===》
设置了keepalive属性。使得建立的链接一直保持着就可以了。
语句如下:
if ( setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &flag, len) == -1 ) {

perror("setsockopt");

exit(1);

}
bestoml 2012-04-17
  • 打赏
  • 举报
回复
在你的CLIENT端,SEND后面加一个LOG,看是否执行完第一次后,是否走完了SEND吧.
yayayo780503 2012-04-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

请注意你的服务器
if((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
这个语句,应该改为
if ((recvbytes=recv(client_fd, buf, MAXDATASIZE, 0)) ==-1)

调用accept函数之后,实际用于通信的fd是client_fd,而sockfd只是用于listen(监听)而已。

……
[/Quote]

按楼上的修改后结果如下,但只能运行一个send,没有继续发送。高手再帮忙看看,谢谢。
client端
while start
str= 0,len=1

server端
received a connection from
Received: 0,recvbytes=2
景语 2012-04-06
  • 打赏
  • 举报
回复
请注意你的服务器
if((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
这个语句,应该改为
if ((recvbytes=recv(client_fd, buf, MAXDATASIZE, 0)) ==-1)

调用accept函数之后,实际用于通信的fd是client_fd,而sockfd只是用于listen(监听)而已。

linux+gcc 测试传输无误。

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧