I have a simple TCP server program, just create two processes, one process is listening and the other process is for connecting. If I run a simple client program on one machine and this simple server on another machine, it works fine.

Now I want to write a simpe tcp client program using raw socket, I filled the IP header and TCP header in the SYN packet with SYN=1, the TCP hearder is 20 bytes without options. then I ran the raw socket-based tcp client and server on two different local machines. I used tcpdump to capture packets, and I see that the server machine received the SYN packet. But the server doesn't reply with a SYN/ACK, what are potential problems? thanks!

the main function of the client program is:

void *run(void *arg)
        struct ip ip;
        struct tcphdr tcp;
        int sd;
        const int on = 1;
        struct sockaddr_in sin;

        u_char *packet;
        packet = (u_char *)malloc(60);

        ip.ip_hl = 0x5;
        ip.ip_v = 0x4;
        ip.ip_tos = 0x0;
        ip.ip_len = sizeof(struct ip) + sizeof(struct tcphdr);
        ip.ip_id = htons(12830);
        ip.ip_off = 0x0;
        ip.ip_ttl = 64;
        ip.ip_p = IPPROTO_TCP;
        ip.ip_sum = 0x0;
        ip.ip_src.s_addr = inet_addr("");
        ip.ip_dst.s_addr = inet_addr("");
        ip.ip_sum = in_cksum((unsigned short *)&ip, sizeof(ip));
        memcpy(packet, &ip, sizeof(ip));

        tcp.source = htons(3333);
        tcp.dest = htons(32000);
        tcp.seq = htonl(0x131123);
        tcp.doff = sizeof(struct tcphdr) / 4;
        tcp.syn = 1;
        tcp.window = htons(2048);
        tcp.check = 0;
        tcp.check = in_cksum_tcp(ip.ip_src.s_addr, ip.ip_dst.s_addr, (unsigned short *)&tcp, sizeof(tcp));
        memcpy((packet + sizeof(ip)), &tcp, sizeof(tcp));

        if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
                perror("raw socket");

        if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {