ReactOS  0.4.12-dev-418-g3df31a8
tcpsvr.c
Go to the documentation of this file.
1 /* tcpServer.c
2  *
3  * Simple Winsock TCP server test.
4  * Later will be used as base for ReactOS telnetd
5  *
6  * HISTORY:
7  * 6-15-02 - Added Winsock support to UNIX tcp test
8  * 6-16-02 - Removed Unix support
9  * 6-17-02 - Added extra comments to code
10  *
11  */
12 
13 #include <winsock2.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <io.h>
17 
18 #undef ERROR
19 #define SUCCESS 0
20 #define ERROR 1
21 
22 #define END_LINE 0x0A
23 #define SERVER_PORT 23
24 #define MAX_MSG 100
25 
26 /* function readline */
27 int read_line();
28 
29 int main (int argc, char *argv[]) {
30 
31  WORD wVersionRequested;
32  WSADATA WsaData;
33  INT Status;
34  int sd, newSd, cliLen;
35 
36  struct sockaddr_in cliAddr, servAddr;
37  char line[MAX_MSG];
38 
39  wVersionRequested = MAKEWORD(2, 2);
40 
41  Status = WSAStartup(wVersionRequested, &WsaData);
42  if (Status != 0) {
43  printf("Could not initialize winsock dll.\n");
44  return FALSE;
45  }
46 
47  /* create socket */
49  if(sd<0) {
50  perror("cannot open socket ");
51  WSACleanup();
52  return ERROR;
53  }
54 
55  /* bind server port */
56  servAddr.sin_family = AF_INET;
57  servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
58  servAddr.sin_port = htons(SERVER_PORT);
59 
60  if(bind(sd, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) {
61  perror("cannot bind port ");
62  WSACleanup();
63  return ERROR;
64  }
65 
66  listen(sd,5);
67 
68  while(1) {
69 
70  printf("%s: \n"
71  "To start test, Please telnet to localhost (127.0.0.1) port 23 \n"
72  "When connected input raw data followed by End of Line\n"
73  "Test is now running on TCP port %u\n",argv[0],SERVER_PORT);
74 
75  cliLen = sizeof(cliAddr);
76  newSd = accept(sd, (struct sockaddr *) &cliAddr, &cliLen);
77  if(newSd<0) {
78  perror("cannot accept connection ");
79  WSACleanup();
80  return ERROR;
81  }
82 
83  /* init line */
85 
86  /* receive segments */
87  while(read_line(newSd,line)!=ERROR) {
88 
89  printf("%s: received from %s:TCP%d : %s\n", argv[0],
90  inet_ntoa(cliAddr.sin_addr),
91  ntohs(cliAddr.sin_port), line);
92  /* init line */
94 
95  } /* while(read_line) */
96 
97  } /* while (1) */
98 
99 }
100 
101 
102 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
103 /* this function is experimental.. I don't know yet if it works */
104 /* correctly or not. Use Steven's readline() function to have */
105 /* something robust. */
106 /* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
107 
108 /* rcv_line is my function readline(). Data is read from the socket when */
109 /* needed, but not byte after bytes. All the received data is read. */
110 /* This means only one call to recv(), instead of one call for */
111 /* each received byte. */
112 /* You can set END_CHAR to whatever means endofline for you. (0x0A is \n)*/
113 /* read_lin returns the number of bytes returned in line_to_return */
114 int read_line(int newSd, char *line_to_return) {
115 
116  static int rcv_ptr=0;
117  static char rcv_msg[MAX_MSG];
118  static int n;
119  int offset;
120 
121  offset=0;
122 
123  while(1) {
124  if(rcv_ptr==0) {
125  /* read data from socket */
126  memset(rcv_msg,0x0,MAX_MSG); /* init buffer */
127  n = recv(newSd, rcv_msg, MAX_MSG, 0); /* wait for data */
128  if (n<0) {
129  perror(" cannot receive data ");
130  return ERROR;
131  } else if (n==0) {
132  printf(" connection closed by client\n");
133  closesocket(newSd);
134  WSACleanup();
135  return ERROR;
136  }
137  }
138 
139  /* if new data read on socket */
140  /* OR */
141  /* if another line is still in buffer */
142 
143  /* copy line into 'line_to_return' */
144  while(*(rcv_msg+rcv_ptr)!=END_LINE && rcv_ptr<n) {
145  memcpy(line_to_return+offset,rcv_msg+rcv_ptr,1);
146  offset++;
147  rcv_ptr++;
148  }
149 
150  /* end of line + end of buffer => return line */
151  if(rcv_ptr==n-1) {
152  /* set last byte to END_LINE */
153  *(line_to_return+offset)=END_LINE;
154  rcv_ptr=0;
155  return ++offset;
156  }
157 
158  /* end of line but still some data in buffer => return line */
159  if(rcv_ptr <n-1) {
160  /* set last byte to END_LINE */
161  *(line_to_return+offset)=END_LINE;
162  rcv_ptr++;
163  return ++offset;
164  }
165 
166  /* end of buffer but line is not ended => */
167  /* wait for more data to arrive on socket */
168  if(rcv_ptr == n) {
169  rcv_ptr = 0;
170  }
171 
172  } /* while */
173 }
174 
175 
static int argc
Definition: ServiceArgs.c:12
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
GLint x0
Definition: linetemp.h:95
#define htonl(x)
Definition: module.h:212
#define MAKEWORD(a, b)
Definition: typedefs.h:247
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
GLintptr offset
Definition: glext.h:5920
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
GLdouble n
Definition: glext.h:7729
#define INADDR_ANY
Definition: StrAddr.c:4
int main(int argc, char *argv[])
Definition: tcpsvr.c:29
#define argv
Definition: mplay32.c:18
int32_t INT
Definition: typedefs.h:56
#define ntohs(x)
Definition: module.h:208
#define closesocket
Definition: main.c:39
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
Definition: parser.c:48
#define inet_ntoa(addr)
Definition: inet.h:100
#define END_LINE
Definition: tcpsvr.c:22
#define ERROR
Definition: tcpsvr.c:20
unsigned short WORD
Definition: ntddk_ex.h:93
static const WCHAR sd[]
Definition: suminfo.c:287
#define SERVER_PORT
Definition: tcpsvr.c:23
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
Status
Definition: gdiplustypes.h:24
struct in_addr sin_addr
Definition: winsock.h:512
#define MAX_MSG
Definition: tcpsvr.c:24
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
#define AF_INET
Definition: tcpip.h:117
#define SOCK_STREAM
Definition: tcpip.h:118
#define htons(x)
Definition: module.h:213
int read_line()
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
short sin_family
Definition: winsock.h:510
#define printf
Definition: config.h:203