I want to get a IP address from DHCP server to my PIC 18F4520 device, and I used mikroc SPI Ethernet Library to program my PIC. I made a code and it is not working. I want to get IP address and display it on a LCD.Can any one help me how to do that?
#include "__EthEnc28j60.h"
#include "__EthEnc28j60Private.h"
// LCD module connections
sbit LCD_RS at LATB4_bit;
sbit LCD_EN at LATB5_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
/*// SD module connections
sbit Mmc_Chip_Select at LATC0_bit; // for writing to output pin always use latch
(PIC18 family)
sbit Mmc_Chip_Select_Direction at TRISC0_bit;
// End SD module connections*/
//ENC28j60 connection
sbit SPI_Ethernet_CS at LATC1_bit;
sbit SPI_Ethernet_Rst at LATC0_bit;
sbit SPI_Ethernet_CS_Direction at TRISC1_bit;
sbit SPI_Ethernet_Rst_Direction at TRISC0_bit;
//End ENC28j60 connection
const char httpHeader[] = "HTTP/1.1 200 OK\nContent-type: "; // HTTP header
const char httpMimeTypeHTML[] = "text/html\n\n"; // HTML MIME type
const char httpMimeTypeScript[] = "text/plain\n\n"; // TEXT MIME type
// default html page
char indexPage[] =
"<html><head><title>mikroElektronika</title></head><body>\
<h3 align=center>MikroElektronika Home Automatization System</h3>\
<form name=\"input\" action=\"/\" method=\"get\">\
<table align=center width=200 bgcolor=#4974E2 border=2><tr>\
<td align=center colspan=2><font size=4 color=white><b>Heat Control</b></font>\
</td></tr><tr><td align=center bgcolor=#4974E2><input name=\"tst1\" width=60 \
type=\"submit\" value=\"ON\"></td><td align=center bgcolor=#FFFF00>\
<input name=\"tst2\" type=\"submit\" value=\"OFF\"></td></tr></table>\
</form></body></html>";
// network parameters
char myMacAddr[6] = {0x00, 0x14, 0xA5, 0x76, 0x19, 0x3f}; // my MAC address
char myIpAddr[4] = {0, 0, 0, 0}; // my IP address
unsigned char getRequest[20]; // HTTP request buffer
unsigned int SPI_Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort,
unsigned int localPort, unsigned int reqLength, TEthPktFlags *flags)
{
unsigned int len; // my reply length
if(localPort != 80) return(0); // I listen only to web request on port 80
// get 10 first bytes only of the request, the rest does not matter here
for(len = 0 ; len < 15 ; len++) getRequest[len] = SPI_Ethernet_getByte();
getRequest[len] = 0;
if(memcmp(getRequest, "GET /", 5)) return(0); // only GET method
if(!memcmp(getRequest+11, "ON", 2)) // do we have ON command
PORTB.F0 = 1; // set PORTB bit0
else
if(!memcmp(getRequest+11, "OFF", 3)) // do we have OFF command
PORTB.F0 = 0; // clear PORTB bit0
if (PORTB.F0)
{
memcpy(indexPage+340, "#FFFF00", 6); // highlight (yellow) ON
memcpy(indexPage+431, "#4974E2", 6); // clear OFF
}
else
{
memcpy(indexPage+340, "#4974E2", 6); // clear ON
memcpy(indexPage+431, "#FFFF00", 6); // highlight (yellow) OFF
}
len = SPI_Ethernet_putConstString(httpHeader); // HTTP header
len += SPI_Ethernet_putConstString(httpMimeTypeHTML); // with HTML MIME type
len += SPI_Ethernet_putString(indexPage); // HTML page first part
return len; // return to the library with the number of bytes to transmit
}
unsigned int SPI_Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort,
unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
{
return 0; // back to the library with the length of the UDP reply
}
unsigned long i, size, j, k;
char filename[14] = "ASHAN.TXT"; // File names
int txt2,*pi;
unsigned short character[20];
unsigned short *contentBuffer;
void main(){
ADCON1 |= 0x0D; // Configure AN0 and AN1 pins as analog
CMCON |= 7; // coparators off
TRISA = 0xff ;
PORTA = 0 ;
PORTB = 0 ; //PORTB output
TRISB = 0 ;
PORTC = 0 ;
TRISC = 0b11011100 ; // set PORTC as input except for bits 0 (RESET) and 1 (CS)
Delay_ms(100);
//Initialize LCD
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF );
Lcd_Out(1, 1, "Status:");
Lcd_Cmd(_LCD_SECOND_ROW);
SPI1_Init();
SPI_Ethernet_Init(myMacAddr, myIpAddr,1);
SPI_Ethernet_initDHCP(5); // get network configuration from DHCP server, wait 5 sec for the response
memcpy(myIpAddr, Spi_Ethernet_getIpAddress(),4) ; // get assigned IP address
Lcd_Out_Cp(myIpAddr);
}
First think I'd do it's to run Wireshark and see if your DHCP discovery hits the wire or not, from that point you decide where the troubleshooting must be focused on...
Related
GOAL: write a simple packet filter using BPF. The packet filter should allow you to choose the interface.
PROBLEM: if I uncomment the third to last instruction in the code (where there is a call to recvfrom, the execution just hangs and I can't see no output (neither "buffer zeroed" which I should be able to see in the stdout).
QUESTIONS: 1) how can I fix it? 2) why the programs hangs during the execution and doesn't show the first printf output? 3) how can I receive from ANY interface?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <linux/filter.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if.h>
#define DEFAULT_IF "wlan0"
/* definisco programma bpf */
/* tcpdump -i lo icmp -dd */
struct sock_filter bpfcode[] = {
{ 0x28, 0, 0, 0x0000000c }, /* (000) ldh [12] */
{ 0x15, 0, 3, 0x00000800 }, /* (001) jeq #0x800 jt 2 jf 5 */
{ 0x30, 0, 0, 0x00000017 }, /* (002) ldb [23] */
{ 0x15, 0, 1, 0x00000001 }, /* (003) jeq #0x1 jt 4 jf 5 */
{ 0x6, 0, 0, 0x00040000 }, /* (004) ret #262144 */
{ 0x6, 0, 0, 0x00000000 }, /* (005) ret #0 */
};
int main(int argc, char *argv[])
{
struct sock_fprog bpf = {
sizeof(bpfcode) / sizeof(struct sock_filter),
bpfcode
};
socklen_t saddr_len = sizeof(struct sockaddr_ll);
struct sockaddr_ll addr;
unsigned char *buffer;
char ifname[IFNAMSIZ];
int ret, sfd, rval;
buffer = calloc(1, 65536);
if (!buffer) {
perror("calloc");
return -1;
}
// prendi nome interfaccia
if (argc > 1)
strcpy(ifname, argv[1]);
else
strcpy(ifname, DEFAULT_IF);
// creazione raw socket
sfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (sfd < 0) {
perror("socket");
return -1;
}
// attacco filtro alla socket
ret = setsockopt(sfd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
if (ret < 0) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// quando si usa packet socket bisogna settare sll_protocol e
// sll_ifindex se si vuol fare il bind ad una specifica interfaccia
memset(&addr, 0, sizeof(addr));
addr.sll_family = AF_PACKET;
addr.sll_protocol = htons(ETH_P_ALL);
addr.sll_ifindex = if_nametoindex(ifname);
printf("index %d", addr.sll_ifindex);
// viene assegnato un indirizzo al socket
if (bind(sfd, (struct sockaddr *) &addr,
sizeof(struct sockaddr_ll)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// ricevo traffico
if (!buffer[0])
printf("buffer zeroed");
// rval = recvfrom(sfd, buffer, 65536, 0, (struct sockaddr *)&addr,
// &saddr_len);
if (buffer[0])
printf("something was written in the buffer");
return 0;
}
How do I fix it?
What do you want to fix exactly? See below.
Why the programs hangs during the execution and doesn't show the first printf output?
Both printf() do work, except you're not printing any line breaks ('\n') at the end of your messages, so the system does not flush your message to the console. Just end your messages with line breaks and you will see your messages as expected.
As for the hang, this is simply because recvfrom() waits until a packet arrives. Well, not just any packet in your case, since you are filtering on ICMP. Ping your interface from the outside, and the program should resume. Alternatively, for debugging your C program, just keep { 0x6, 0, 0, 0x00040000 } (return non-zero) in your BPF program, and any received packet should do.
How can I receive from ANY interface?
How to bind a socket to multiple interfaces
Im trying to use memory map I/O netlink to transfer bulk packets from kernel to user space, and I followed a guide document from Patrick McHardy 1. However, when I try to setup the shared ring buffer in user space by using:
setsockopt(sock_fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req));
setsockopt(sock_fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req));
Both functions return -1, and the errno is 1, which means the descriptor is invalid. Im confused about that because I also referred to many other source codes and they can setup the ring successfully.
My code is almost the same as Patrick's 1:
int sock_fd = -1;
sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_DECODE);
if (sock_fd < 0)
return -1;
bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
/* init the mmap buffer */
unsigned int block_size = 16 * getpagesize();
struct nl_mmap_req req = {
.nm_block_size = block_size,
.nm_block_nr = 64,
.nm_frame_size = 16384,
.nm_frame_nr = 64 * block_size / 16384,
};
/* Configure ring parameters */
if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_RX_RING, &req, sizeof(req)) < 0){
if(errno > 0)
printf("%d\n", errno);
}
if (setsockopt(sock_fd, SOL_NETLINK, NETLINK_TX_RING, &req, sizeof(req)) < 0){
if(errno > 0)
printf("%d", errno);
exit(1);
}
This code is built in Ubuntu 14.04, and kernel version is 3.13.0-74-generic.
Anyone idea about it? Thanks a lot.
I'm trying to use RAW sockets to create a ping program. The program I wrote however works only for localhost(127.0.0.1) and does not work for other IP addresses. While analyzing the generated packet in Wireshark, I get a message saying "Unknown ICMP (obsolete or malformed?)". It also tells me that the ICMP checksum is incorrect. I'm posting my code here
char source[20], destination[20];
struct sockaddr_in src, dst;
int addrlen= sizeof(src), recvSize, packetSize;
char *packet;
char *buffer;
struct iphdr* ip;
struct iphdr* ip_reply;
struct icmphdr* icmp;
unsigned short csum(unsigned short *, int);
char* getip();
int main(int argc, char* argv[]){
int pingSocket, optval;
struct protoent *protocol;
if(*(argv + 1) && (!(*(argv + 2)))){
//only one argument provided,assume it is the destination server
strncpy(destination, *(argv + 1), 15);
strncpy(source, getip(), 15);
}
inet_pton(AF_INET, destination, &(dst.sin_addr));
inet_pton(AF_INET, source, &(src.sin_addr));
protocol= getprotobyname("ICMP");
printf("Protocol number for ICMP is %d\n",protocol->p_proto);
pingSocket= socket(AF_INET, SOCK_RAW, protocol->p_proto); // Create socket
if(pingSocket< 0){
perror("Error creating socket: ");
exit(3);
}
printf("Socket created with identifier %d\n", pingSocket);
packetSize= sizeof(struct iphdr) + sizeof(struct icmphdr);
packet = (char *) malloc(packetSize);
buffer = (char *) malloc(packetSize);
ip= (struct iphdr*) packet;
icmp= (struct icmphdr*) (packet+ sizeof(struct iphdr));
memset(packet, 0, packetSize);
//Fill up the IP header
ip->ihl= 5;
ip->version= 4;
ip->tos= 0;
ip->tot_len = htons(packetSize);
ip->id = htons(0);
ip->frag_off= 0;
ip->ttl = 255;
ip->protocol= protocol->p_proto;
ip->saddr= src.sin_addr.s_addr;
ip->daddr= dst.sin_addr.s_addr;
setsockopt(pingSocket, protocol->p_proto, IP_HDRINCL, &optval, sizeof(int)); //HDRINCL to tell the kernel that the header is already included
icmp->type= ICMP_ECHO;
icmp->code= 0;
icmp->un.echo.id= rand();
icmp->un.echo.sequence= rand();
icmp->checksum= 0;
icmp->checksum = csum((unsigned short *)icmp, sizeof(struct icmphdr));
dst.sin_family= AF_INET;
sendto(pingSocket, packet, packetSize, 0, (struct sockaddr *)&dst, sizeof(dst));
printf("Sent ping request with size %d to %s\n", ip->tot_len, destination);
printf("Request's IP ID: %d and IP TTL: %d\n", ip->id, ip->ttl);
printf("Packet: \n%s\n", packet);
// Wait for response
if( (recvSize= recvfrom(pingSocket, buffer, sizeof(struct iphdr)+sizeof(struct icmphdr), 0, (struct sockaddr *)&dst, &addrlen)) < 0){
perror("Receive error: ");
}
else{
printf("Received a reply from %s of size %d\n", destination, recvSize);
ip_reply= (struct iphdr*) buffer;
printf("Reply's IP ID: %d and IP TTL: %d\n", ip_reply->id, ip_reply->ttl);
}
free(packet);
free(buffer);
close(pingSocket);
return 0;
}
unsigned short csum(unsigned short *ptr, int nbytes)
{
register long sum;
u_short oddbyte;
register u_short answer;
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
*((u_char *) & oddbyte) = *(u_char *) ptr;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
char* getip()
{
char buffer[256];
struct hostent* h;
gethostname(buffer, 256);
h = gethostbyname(buffer);
return inet_ntoa(*(struct in_addr *)h->h_addr);
}
I read somewhere that someone fixed this issue by setting the ICMP checksum to Zero first and then calculating it. This however doesn't work for me. Please help me out :)
I have application which uses sockets to transfer data between two clients. It uses a single socket to communicate control and data traffic (over UDP).
Qos and tos fields of IP header can be changed using
setsockopt(sockfd, IPPROTO_IP, IP_TOS, &tos, toslen);
setsockopt(sockfd, SOL_SOCKET, SO_PRIORITY, &cos, coslen);
But how many calls to setsockopt (to the same socket) is too many?
For example, lets assume it will be called every 1ms.
To narrow question scope, I am asking about modern linux system (generic explanation is more than welcomed).
Here is an example to demonstrate it (this is the sending-only part of the application):
#include <stdlib.h>
#include <memory.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define NPACK 10000
#define PORT 44444
#define BUFLEN 128
void diep(char *s) {
perror(s);
exit(1);
}
#define SRV_IP "12.34.56.78"
int main(void) {
struct sockaddr_in si_other, si_me;
int s, i, slen = sizeof(si_other);
int toss[2] = { 56, 160 }, coss[] = { 1, 3 };
char buf[BUFLEN];
//Create UDP socket
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
diep("socket");
//Create remote socket
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr) == 0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
//Create local socket and bind to it.
memset((char *) &si_me, 0, sizeof(si_me));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, &si_me, sizeof(si_me)) == -1)
diep("bind");
//Loop on number of packets
for (i = 0; i < NPACK; i++) {
sprintf(buf, "This is packet %d, %d\n", i, toss[i % 2]);
printf("Sending packet %d. %s", i, buf);
//Change tos and cos. odd packets high priority , even packets low priority.
setsockopt(s, IPPROTO_IP, IP_TOS, &toss[i % 2], sizeof(int));
setsockopt(s, SOL_SOCKET, SO_PRIORITY, &coss[i % 2], sizeof(int));
//Send!
if (sendto(s, buf, strlen(buf), 0, &si_other, slen) == -1)
diep("sendto()");
}
close(s);
return 0;
}
NOTES:
Both control and data should share the same socket (same UDP source port).
Multiple threads will use the same socket (so some locking mechanism needed between setsockopt and sendto; but this is outside the scope of the question).
SO_PRIORITY is linux only.
Okay, I've scoured the net (literally) for the last ten hours, but no one seems to have a tutorial explaining how to create a C++ Proxy server in Windows. Several times I've run into functions that work solely for UNIX, and it's been a frustrating experience. I am VERY new to socket programming, but I need to have this finished within 48 hours. It seems impossible right now.
Requirements for the program:
The daemon listens for TCP connections on a specified port number.
When a new client initiates a TCP connection request, the daemon accepts
the request and establishes a TCP connection with the new client.
The daemon forks a child process that is dedicated to handling the new
client.
The child process establishes a TCP connection to a pre-assigned port on the
actual targeted server.
The child process falls into a loop in which it acts as an intermediator
exchanging data (reading/writing or writing/reading) between the client and
the targeted server.
Once a child has been forked, the daemon process resumes listening for
additional TCP connections.
I've run a provided winsock client and program to get a better idea of how sockets work, but it's getting me nowhere fast. pid_t is unavailable for windows, so forking is out of the question (or so I've gathered from the 10 hours of net-scouring).
If you can point me in the right direction for being able to use Internet Explorer's proxy settings (the IP and Port number feature) in combination with the program to yield webpages that are redirected to another server, that would be great.
/* client.c - code for example client program that uses TCP */
#ifndef unix
#include<winsock2.h>
#include <windows.h>
#include <winsock.h>
#pragma comment(lib, "ws2_32.lib")
#else
#define closesocket close
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#endif
#include <stdio.h>
#include <string.h>
#include <iostream>
#define PROTOPORT 5193 /* default protocol port number */
extern "C";
char localhost[] = "localhost"; /* default host name */
#define QLEN 6 /* size of request queue */
int visits = 0; /* counts client connections */
/*------------------------------------------------------------------------
* Program: client
*
* Purpose: allocate a socket, connect to a server, and print all output
*
* Syntax: client [ host [port] ]
*
* host - name of a computer on which server is executing
* port - protocol port number server is using
*
* Note: Both arguments are optional. If no host name is specified,
* the client uses "localhost"; if no protocol port is
* specified, the client uses the default given by PROTOPORT.
*
*------------------------------------------------------------------------
*/
int main(int argc, char *argv[])
{
struct hostent *ptrh; /* pointer to a host table entry */
struct protoent *ptrp; /* pointer to a protocol table entry */
struct sockaddr_in sad; /* structure to hold an IP address */
int port; /* protocol port number */
char *host; /* pointer to host name */
int n; /* number of characters read */
char buf[1000]; /* buffer for data from the server */
struct sockaddr_in cad; /* structure to hold client's address */
int sd, sd2; /* socket descriptors */
int alen; /* length of address */
#ifdef WIN32
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
#endif
memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */
sad.sin_family = AF_INET; /* set family to Internet */
sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */
/* Check command-line argument for protocol port and extract */
/* port number if one is specified. Otherwise, use the default */
/* port value given by constant PROTOPORT */
if (argc > 2) { /* if protocol port specified */
port = atoi(argv[2]); /* convert to binary */
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for legal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s\n",argv[2]);
exit(1);
if (argc > 1) { /* if argument specified */
port = atoi(argv[1]); /* convert argument to binary */
} else {
port = PROTOPORT; /* use default port number */
}
if (port > 0) /* test for illegal value */
sad.sin_port = htons((u_short)port);
else { /* print error message and exit */
fprintf(stderr,"bad port number %s\n",argv[1]);
exit(1);
}
/* Map TCP transport protocol name to protocol number */
(int)(ptrp = getprotobyname("tcp"));
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map \"tcp\" to protocol number");
exit(1);
}
/* Check host argument and assign host name. */
if (argc > 1) {
host = argv[1]; /* if host argument specified */
} else {
host = localhost;
}
/* Convert host name to equivalent IP address and copy to sad. */
ptrh = gethostbyname(host);
if ( ((char *)ptrh) == NULL ) {
fprintf(stderr,"invalid host: %s\n", host);
exit(1);
}
memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length);
/* Map TCP transport protocol name to protocol number. */
(int)(ptrp = getprotobyname("tcp"));
if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) {
fprintf(stderr, "cannot map \"tcp\" to protocol number");
exit(1);
}
/* Create a socket. */
sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
if (sd < 0) {
fprintf(stderr, "socket creation failed\n");
exit(1);
}
/* Connect the socket to the specified server. */
connect(sd, (struct sockaddr *)&sad, sizeof(sad));
if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"connect failed\n");
exit(1);
}
/* Bind a local address to the socket */
bind(sd, (struct sockaddr *)&sad, sizeof(sad));
if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
fprintf(stderr,"bind failed\n");
exit(1);
}
/* Specify size of request queue */
listen(sd, QLEN);
if (listen(sd, QLEN) < 0) {
fprintf(stderr,"listen failed\n");
exit(1);
}
/* Repeatedly read data from socket and write to user's screen. */
n = recv(sd, buf, sizeof(buf), 0);
while (n > 0) {
int _write(int fd, const void *buffer, unsigned int count);
n = recv(sd, buf, sizeof(buf), 0);
}
/* Main server loop - accept and handle requests */
while (1) {
alen = sizeof(cad);
printf("\nI'm waiting for connections ...");
fflush(stdout);
if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
fprintf(stderr, "accept failed\n");
exit(1);
}
printf("\nI received one connection.\n");
fflush(stdout);
visits++;
sprintf_s(buf,"This server has been contacted %d time%s\n",
visits,visits==1?".":"s.");
send(sd2,buf,strlen(buf),0);
printf("\nI sent the client a string.\n");
fflush(stdout);
closesocket(sd2);
}
/* Close the socket. */
closesocket(sd);
/* Terminate the client program gracefully. */
exit(0);
}
}
If you've made it this far, I thank you for your vigilance. Wish me luck...