用ANSI C编写的套接字客户端和套接字服务器中的字符数组

用ANSI C编写的套接字客户端和套接字服务器中的字符数组,c,arrays,sockets,char,C,Arrays,Sockets,Char,我正在尝试用C编写基于套接字的简单客户端和服务器。 客户端发送字符数组的大小(包括“\0”的最后一个单元格),然后发送字符数组。 服务器从客户端获取大小并尝试为字符数组分配内存。 在此之后,服务器将查找一个空格,并将字符从索引0复制到空格中,将其粘贴到数组末尾,然后将其发送回客户端(如果没有空格,则服务器将发送一个数组) 我注意到有时候我会 -- |00| |02| -- 从服务器接收的数组末尾的字符。 我使用valgrind运行了服务器和客户端,结果表明问题出在服务器上 代码如下 客户: #i

我正在尝试用C编写基于套接字的简单客户端和服务器。 客户端发送字符数组的大小(包括“\0”的最后一个单元格),然后发送字符数组。 服务器从客户端获取大小并尝试为字符数组分配内存。 在此之后,服务器将查找一个空格,并将字符从索引0复制到空格中,将其粘贴到数组末尾,然后将其发送回客户端(如果没有空格,则服务器将发送一个数组)

我注意到有时候我会 -- |00| |02| -- 从服务器接收的数组末尾的字符。 我使用valgrind运行了服务器和客户端,结果表明问题出在服务器上

代码如下

客户:

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



int
main ()
{
    int sockfd;
    socklen_t len;
    struct sockaddr_in address;
    int result;

    char ch;
    char *string;
    int i;

    sockfd = socket (AF_INET, SOCK_STREAM, 0);

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr ("127.0.0.1"); 
    address.sin_port = htons (9734);
    len = sizeof (address);

    result = connect (sockfd, (struct sockaddr *) &address, len);

    if (result == -1)
    {
        perror ("oops: netclient");
        exit (1);
    }

    string = (char*)malloc(sizeof(char));

    for (i =0; ch = getchar(); i++)
    {
        string = (char*)realloc(string, (i+1)*sizeof(char));

        if(ch != '\n')
            string[i] = ch;
        else if (ch == '\n')
        {
            string[i]='\0';
            break;
        }
    }

    printf("%s\n", string);
    printf("%d\n", i);
    i=i+1;

    write (sockfd, &i, 4);

    write (sockfd, string, i);


    read (sockfd, &i, 4);


    string = (char*)realloc(string, i*sizeof(char));

    read (sockfd, string, i); 

    printf("String recieved: %s\n", string);

    close (sockfd);

    free(string);

    exit (0);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int
主要()
{
int-sockfd;
索克伦;
地址中的结构sockaddr_;
int结果;
char ch;
字符*字符串;
int i;
sockfd=套接字(AF_INET,SOCK_STREAM,0);
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr(“127.0.0.1”);
address.sin_port=htons(9734);
len=sizeof(地址);
结果=连接(sockfd,(结构sockaddr*)和地址,len);
如果(结果==-1)
{
perror(“oops:netclient”);
出口(1);
}
字符串=(char*)malloc(sizeof(char));
对于(i=0;ch=getchar();i++)
{
string=(char*)realloc(string,(i+1)*sizeof(char));
如果(ch!='\n')
字符串[i]=ch;
else if(ch='\n')
{
字符串[i]='\0';
打破
}
}
printf(“%s\n”,字符串);
printf(“%d\n”,i);
i=i+1;
写入(sockfd和i,4);
写入(sockfd,string,i);
阅读(sockfd和i,4);
字符串=(char*)realloc(字符串,i*sizeof(char));
读(sockfd,string,i);
printf(“收到的字符串:%s\n”,字符串);
关闭(sockfd);
自由(弦);
出口(0);
}
和服务器:

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

int
main ()
{
    int server_sockfd, client_sockfd; 
    socklen_t server_len, client_len; 
    struct sockaddr_in server_address; 
    struct sockaddr_in client_address; 

    server_sockfd = socket (AF_INET, SOCK_STREAM, 0); 
    server_address.sin_family = AF_INET; /*ipv4*/
    server_address.sin_addr.s_addr = htonl (INADDR_ANY); 
    server_address.sin_port = htons (9734);
    server_len = sizeof (server_address);
    bind (server_sockfd, (struct sockaddr *) &server_address, server_len); 


    listen (server_sockfd, 5); 
    signal (SIGCHLD, SIG_IGN);

    while (1)
    {
        char *string;
        int i, j, k, l=0; /*variables to iteration*/
        printf ("server waiting\n");


        client_len = sizeof (client_address);
        client_sockfd = accept (server_sockfd,
                (struct sockaddr *) &client_address,
                &client_len); 


        if (fork () == 0)
        {


            read (client_sockfd, &i, 4);
            printf("recieved int %d\n", i);
            string = (char*)malloc(sizeof(char) * (i));
            read (client_sockfd, string, i);
            printf("\nSTRING recieved: %s \n", string);

            for(j=0; string[j]!='\0'; j++)
            {
                if(string[j] == ' ')
                {
                    i = i+j; /*size to enlarge*/
                    break;
                }
            }

            /*sending new size*/
            write(client_sockfd, &i, 4);

            /*enlarge the string*/
            string = (char*)realloc(string, i*sizeof(char));

            for (k = i-j-1; k < i-1 ; k ++)
            {
                string[k] = string[l];
                l++;
            }
            string[k+1] = '\0';

            write(client_sockfd, string, i);


            close (client_sockfd);

            free(string);

            exit (0);
        }



        else
        {
            close (client_sockfd);
        }
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int
主要()
{
int server_sockfd,client_sockfd;
socklen\u t服务器、客户端;
服务器地址中的结构sockaddr\u;
客户端地址中的结构sockaddr\u;
server\u sockfd=socket(AF\u INET,SOCK\u STREAM,0);
服务器\u address.sin\u family=AF\u INET;/*ipv4*/
服务器地址sin\u addr.s\u addr=htonl(INADDR\u ANY);
服务器地址.sin\u端口=htons(9734);
server\u len=sizeof(服务器地址);
绑定(服务器\u sockfd,(结构sockaddr*)和服务器\u地址,服务器\u len);
听(服务器_sockfd,5);
信号(信号灯、信号灯);
而(1)
{
字符*字符串;
int i,j,k,l=0;/*迭代变量*/
printf(“服务器等待\n”);
客户地址=sizeof(客户地址);
客户端\u sockfd=接受(服务器\u sockfd,
(结构sockaddr*)和客户端地址,
&客户(本地);;
if(fork()==0)
{
读取(客户机和i,4);
printf(“已接收整数%d\n”,i);
字符串=(char*)malloc(sizeof(char)*(i));
读取(client_sockfd,string,i);
printf(“\n收到的字符串:%s\n”,字符串);
对于(j=0;字符串[j]!='\0';j++)
{
如果(字符串[j]='')
{
i=i+j;/*放大尺寸*/
打破
}
}
/*发送新尺寸*/
写入(客户端和i,4);
/*扩大范围*/
字符串=(char*)realloc(字符串,i*sizeof(char));
对于(k=i-j-1;k
您的代码忽略
read()的返回值。

不能忽略此值。socket接口不能保证仅仅因为您请求了4个字节,就可以实际返回4个字节。socket接口仅保证您将至少返回一个字节。必须继续调用
read()
,直到获得所需的所有字节

当您在几行之后读取字符串时,情况也是如此

即使您的程序现在看起来可以工作,但这类问题会在不可预知的情况下突然出现,如繁忙的机器或网络,您将无法复制它,并且您的程序将变得不可靠

        read (client_sockfd, &i, 4);