gpt4 book ai didi

c - C 中的套接字 : Client can not receive and print out the array of strings sent from server

转载 作者:行者123 更新时间:2023-11-30 19:04:00 25 4
gpt4 key购买 nike

我编写的套接字程序是客户端向服务器发送一个字符串数组,服务器接收该数组并发回给客户端。我的服务器可以在服务器端成功打印出字符串数组reply[]。但在客户端,却无法打印出结果。这是我的代码

客户端.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define PORT 4444

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

if (argc < 2 || argc > 3) // Test for correct number of arguments
printf("Parameter(): <Server Address>");

char *servIP = argv[1]; // arg: server IP address (dotted quad)
int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[1024];
char **reply = malloc(20*sizeof(char *));

// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");

// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");

// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");

//Read arrays from input file
FILE *fptr;
fptr = fopen("client1.inputdat", "r"); //open input file to read
if (fptr != NULL)
{
int line =0;
while(fgets(buffer, sizeof(buffer), fptr)) { //read line by line of the input file
line++;
if (line==1) {
printf("\n");
printf("Unsorted array: %s\n", buffer);
// Send arrays to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
if(recv(clientSocket, &reply, 20*sizeof(char *), 0) < 0){
printf("Error in receiving data.\n");
}
else {
int i;
printf("Sorted array:");
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
printf("%s ", reply[i]);
}
}
}
}
fclose(fptr);
}
else {
printf("File does not exits");
exit(1);
}
return 0;
}

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444

int main(){

int sockfd, ret;
struct sockaddr_in serverAddr; // Local address

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

char buffer[1024];
pid_t childpid;

// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");

// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface

// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
exit(1);
}
printf("Bind to port %d\n", 4444);

// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in binding.\n");
}


while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");

//Handle concurrency by using fork
if((childpid = fork()) == 0){
close(sockfd);

while(1){
recv(newSocket, buffer, 1024, 0);
int i=0;
char *array[20];
char **reply = malloc(20*sizeof(char *));
char *p = strtok(buffer, ",");
while (p!=NULL) {
array[i++] = p;
p = strtok(NULL, ","); //stroke received string into tokens
}
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
strcpy(reply[i], array[i]); //input tokens into array
printf("%s ", reply[i]);
}

send(newSocket, reply, 20*sizeof(char *), 0);
bzero(reply, sizeof(reply));
//}
}
}

}
close(newSocket);
return 0;
}

那么,我该如何解决这个问题,以便客户端可以打印出服务器发送的数组reply[]?谢谢你的补充

最佳答案

好的。你的代码很清楚地表明你不太了解C,更不用说套接字了,但这里有一个新的改进版本,我认为它可以满足你的要求。我的大部分改进都包含在对原始帖子的评论中。我没有在适当的地方检查错误,这在许多其他方面都远非完美,但这会做一些看起来像你想要的事情,而不会崩溃。

您在发送数据时没有任何方式知道您是否收到了所有传输的数据。套接字是流。它以它认为最方便的方式发送数据,而不是您可能喜欢的方式。为了解决这个问题,我要求我们发送 \n每次传输。我们检查 \n并在每次从对方返回数据时继续读取数据。我发送了很多条回复数据后,我发送了一条\n字符,以便客户知道已收到完整的行。我们不需要添加\n来自客户 fgets离开\n在缓冲区的末尾。

你提到了排序,所以作为额外的奖励,我添加了 qsort对数据进行排序。在 compReply函数,我不只是直接从 strcmp 返回值但将其放入 int所以如果需要的话我可以在调试器中看到它。我相信有些编译器会提示我正在做 strcmp两个void *变量。为了保持整洁,您可能需要使用 (char*)a 来转换它们。在将它们传递给 strcmp 之前.

我删除了你的fork以便于调试。抱歉,这一次只允许一个连接。当我写这样的东西时,我通常不会 fork 一个新进程,而是拥有一个 newSocket 值数组并使用 select来决定从哪一个中读取。 (select 函数也可以与 accept 一起使用。)同样,这样调试起来更容易。

strtok函数将找到的字符替换为 null,并返回指向字符串开头的指针。我只是想删除不需要的字符,所以我使用它而不费心接受返回值。这也可以通过以下方式完成:

char *p=strchr(buffer,'\n');
if( NULL != p ) *p=0;

但是strtok更加简洁。

我允许将端口号传递到服务器,但没有将其添加到客户端。哦,好吧。

在让客户端运行之前我测试了服务器

telnet 127.0.0.1 4444

并输入:a,s,d,f,g,h,j,k,l <CR>返回排序后的列表 a,d,f,g,h,j,k,l,s,我也不喜欢结尾的逗号,但我现在不会让它消失。

服务器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 4444
#define BUF_SIZE 1024
static int compReply(const void *a, const void *b)
{
int ret=strcmp(a,b);
return(ret);
}
int main(int argc, char *argv[])
{
int port=4444;
int sockfd, ret;
struct sockaddr_in serverAddr; // Local address

int newSocket;
struct sockaddr_in newAddr;

socklen_t addr_size;

if( argc > 1 ) {
port=atoi(argv[1]);
if( port < 1024 ) {
port=4444;
}
}

// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");

// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface

// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
perror("bind");
exit(1);
}
printf("Bind to port %d\n", port);

// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in listening.\n");
perror("listen");
}

while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");

while(1){
char buffer[BUF_SIZE]={0};
int ret=1;
int count=0;
while(NULL == strchr(buffer,'\n') && ret > 0 && count < sizeof(buffer))
{
ret=recv(newSocket, &buffer[count], sizeof(buffer)-count, 0);
count+=ret;
}
if( ret <= 0 ) {
if( ret < 0 ) {
printf("Problem with recv: %d\n", ret);
}
break;
}
printf("recv: %s\n", buffer);
strtok(buffer,"\n\r"); /* throw away any \r\n */
if( ret> 0 ) {
int i=0;
char reply[20][BUF_SIZE]={0};
char *p = strtok(buffer, ",");
while (p!=NULL) {
strncpy(reply[i],p,BUF_SIZE);
strcat(reply[i],",");
p = strtok(NULL, ","); //stroke received string into tokens
i++;
}
qsort(reply,i,BUF_SIZE,compReply);
for(int jj=0; jj<i; jj++) {
printf("%s ", reply[jj]);
ret=send(newSocket, reply[jj], strlen(reply[jj]), 0);
}
ret=send(newSocket, "\n", 1, 0);
printf("\n");
}
}

close(newSocket);
}
return 0;
}

客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define PORT 4444
#define BUF_SIZE 1024

int main(int argc, char *argv[])
{
char servIP[120]="127.0.0.1";

if( argc > 1 ) {
strncpy(servIP,argv[1],sizeof(servIP));
}

int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[BUF_SIZE];

// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");

// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");

// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");

//Read arrays from input file
FILE *fptr;
fptr = fopen("this.csv", "r"); //open input file to read
if (fptr != NULL) {
while(fgets(buffer, sizeof(buffer), fptr)) //read line by line of the input file
{
char reply[BUF_SIZE]={0};
char repList[20][BUF_SIZE]={0};
int count=0;
int ret=1;
printf("Unsorted array: %s", buffer);
// Send array to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
while(NULL == strchr(reply,'\n') && ret > 0 && count < sizeof(reply))
{
ret=recv(clientSocket, &reply[count],sizeof(reply)-count,0);
count+=ret;
}
if( ret < 0 ) {
printf("Error in receiving data.\n");
}
else {
int i=0;
strtok(reply,"\n\r");
for(char *p=strtok(reply,",");p!=NULL; p=strtok(NULL,","))
{
strncpy(repList[i],p,BUF_SIZE);
i++;
}
printf("Sorted array:");
for (int jj=0; jj<i; jj++) {
printf("%s ", repList[jj]);
}
}
printf("\n");
}
fclose(fptr);
}
else {
printf("File does not exist");
perror("fopen");
exit(1);
}
return 0;
}

这应该会给你一些可以尝试的东西来帮助你继续前进。我希望它有帮助。

关于c - C 中的套接字 : Client can not receive and print out the array of strings sent from server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com