【问题标题】:Client sending data to a port using TCP socket using C客户端使用 C 使用 TCP 套接字向端口发送数据
【发布时间】:2012-05-21 06:42:47
【问题描述】:

我正在用 C 语言编写一个必须处理这种情况的客户端程序:

1- 服务器程序在端口号 X 的客户端发送的端口号 8080 中接收 udp 数据报

2- 服务器在端口号 X 中创建一个新的套接字 (TCP)

3- 使用这个 TCP 套接字,服务器读取客户端发送的字符串

(在本地主机上运行)

我不需要做服务器程序,它已经完成了。第 1 点和第 2 点已涵盖,但我已经花了几天时间试图解决第 3 点,但我无法使其发挥作用>

我为客户得到的代码是这样的:

#define MYPORT 8080


int main(int argc, char *argv[ ]) {

int sockfd;

/* connector’s address information */

struct sockaddr_in their_addr;
struct hostent *he;
int numbytes;

int sockfd2, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];


if (argc != 3) {
    fprintf(stderr, "Usage: %s <hostname> <message>\n", argv[0]);
    exit(1);
}

/* get the host info */

if ((he = gethostbyname(argv[1])) == NULL) {
perror("Error obtaining the client. \n");
    exit(1);
}

else printf("Client obtained\n");

if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    perror("Error creating UDP socket\n");
    exit(1);
}

else printf("UDP Socket done\n");

their_addr.sin_family = AF_INET;

printf("Port: 8080\n");

their_addr.sin_port = htons(MYPORT);

their_addr.sin_addr = *((struct in_addr *)he->h_addr);

memset(&(their_addr.sin_zero), '\0', 8);

 sockfd2 = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd2 < 0) 
    error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
    fprintf(stderr,"ERROR, no such host\n");
    exit(0);
}

//sending port where the TCP socket will be associated
//server client connects correctly to this port 
//and the code it's working fine in this point
if((numbytes = sendto(sockfd, argv[2], strlen(argv[2]), 0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1)

{

perror("Client-sendto() error lol!");

exit(1);

}
//port is sent, now let's connect to the port by tcp and write the string
//not working properly from now on

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, 
     (char *)&serv_addr.sin_addr.s_addr,
     server->h_length);
serv_addr.sin_port = htons(atoi(argv[2]));
if (bind(sockfd2,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    error("ERROR connecting");

listen(sockfd2, 5);
accept(sockfd2, 0, 0);
printf("accepted!\n");

//sending the string to the TCP Port...
if((numbytes = sendto(sockfd2, "hi", 2, 0, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr))) == -1)

{

printf("Client-sendto()-TCP error\n");

exit(1);

}


if (close(sockfd) != 0) printf("Client-sockfd-UDP closing is failed!\n");
else printf("Client-sockfd-UDP successfully closed!\n");
if (close(sockfd) != 0) printf("Client-sockfd2-TCP closing is failed!\n");
else printf("Client-sockfd2-TCP successfully closed!\n");
return 0;

}

代码在前两步有效,但在最后一步,它似乎与 TCP 端口连接不好,因为我的客户端程序结束但我的服务器程序说他收到 null。 当然,我总是发送端口 > 1024

提前致谢,我们将不胜感激。

【问题讨论】:

  • 服务器应该连接回客户端,对吧? (这非常不寻常。)
  • 没有真正回连,服务器通过udp套接字接收到一个端口号X,然后在端口X建立一个tcp连接并从这个新的tcp连接中读取一个字符串,客户端应该发送这个端口的字符串(我猜)
  • bind() 客户端到 TCP 端口,然后告诉服务器它可以将连接发送回该端口;尝试连接/读取时服务器是否返回错误?如果是这样,我猜没有建立实际的连接,因为还没有人接受该端口上的连接。您似乎已经成功地在这里比赛了。
  • 已经修复,我没有收到通过接受调用发回的文件描述符。现在一切正常。感谢 Mat 和所有阅读和回答的人!

标签: c sockets tcp udp client-server


【解决方案1】:
listen(sockfd2, 5);
accept(sockfd2, 0, 0);
printf("accepted!\n");

我还没有阅读您的所有代码,但以上(至少)是错误的。您绝对需要保留accept 的返回值:这是您需要写入的套接字!

accept 为刚刚创建的新 TCP 套接字返回一个文件描述符,用于与您的情况下的“服务器”通信。您需要将其用作将字符串写入的文件描述符。

(之后的 sendto 调用,除了使用错误的套接字外,有点可疑,因为服务器无法确定要读取多少数据/消息停止的位置。传递长度为 3 (包含\0 字节,就不会那么可疑了。)

【讨论】:

  • 非常感谢!!!它已经工作正常了。我的错,这是一个新手失败。再次感谢,现在一切正常:D
猜你喜欢
  • 1970-01-01
  • 2016-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
相关资源
最近更新 更多