ReactOS 0.4.16-dev-329-g9223134
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 */
28
29int 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 */
84 memset(line,0x0,MAX_MSG);
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 */
93 memset(line,0x0,MAX_MSG);
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 */
114int 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
CHAR FAR *WSAAPI inet_ntoa(IN IN_ADDR in)
Definition: addrconv.c:160
#define FALSE
Definition: types.h:117
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
int main()
Definition: test.c:6
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned short WORD
Definition: ntddk_ex.h:93
#define printf
Definition: freeldr.h:97
Status
Definition: gdiplustypes.h:25
GLdouble n
Definition: glext.h:7729
GLintptr offset
Definition: glext.h:5920
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define INADDR_ANY
Definition: inet.h:80
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
#define htonl(x)
Definition: module.h:214
static const WCHAR sd[]
Definition: suminfo.c:286
#define argv
Definition: mplay32.c:18
#define closesocket
Definition: ncftp.h:477
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: parser.c:49
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
#define END_LINE
Definition: tcpsvr.c:22
int read_line()
#define ERROR
Definition: tcpsvr.c:20
#define MAX_MSG
Definition: tcpsvr.c:24
#define SERVER_PORT
Definition: tcpsvr.c:23
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60