SOCKET编程下的局域网聊天工具,学习了。。。
一些链接:
服务器端:
main.cpp
/* chat online tool server */
/* the side of wait for connection */
/* if the project has a linking error like follows:
undefined reference to `inet_addr@4'
undefined reference to `gethostbyname@4'
undefined reference to `WSAGetLastError@0'
undefined reference to `inet_ntoa@4'
undefined reference to `WSAStartup@8'
undefined reference to `inet_ntoa@4'
undefined reference to `socket@12'
undefined reference to `htons@4'
undefined reference to `bind@12'
undefined reference to `listen@8'
undefined reference to `accept@12'
undefined reference to `recv@16'
undefined reference to `send@16'
undefined reference to `shutdown@8'
undefined reference to `closesocket@4'
undefined reference to `closesocket@4'
undefined reference to `WSACleanup@0'
the solution is setting the project links -> extra linking options -> input"-lwsock32"(on a compiler) or add "-losock32" when compling on Linux
*/
#include <iostream>
#include <Winsock2.h> // Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly
#include <Windows.h>
#include <process.h>
using namespace std;
/* the self header files */
#include "backgroundColorChanger.h"
#define max_length_message 10000
SOCKET server, client; // 2 SOCKET for chat_online
bool first_time_connection; // to output something different for the first time connection
void mythread(void * param) {
char buffer[max_length_message];
while (1) {
/* recv(SOCKET s, char *buf, int len, int flags): the recv function receives data from a connected socket or a bound connectionless socket */
if (recv(client, buffer, sizeof(buffer), 0) <= 0) { // the connection is interrupted, ask if the user want to quit
cout << endl;
cout << "The connection is interrupted, please quit..." << endl;
break;
}
if (first_time_connection) { // the first connection showed on Server is specil
first_time_connection = false;
cout << "Nightonke_Client: " << endl;
cout << "---" << "Hi, now let's chat!" << endl << endl;
} else {
cout << "Nightonke_Client: " << endl;
cout << "---" << buffer << endl << endl;
}
}
}
int main() {
/* pre_do */
change_color();
first_time_connection = true;
/* WSADATA: this structure is used to store Windows Sockets initialization data returned by a call to WSAStartup */
WSADATA wData;
/* MAKEWORD(2, 2): creates a WORD value by concatenating the specified values */
/* WSAStartup: the WSAStartup function initiates use of the Winsock DLL by a process */
WSAStartup(MAKEWORD(2, 2), &wData);
/* socket(): the socket function creates a socket that is bound to a specific transport service provider */
/* SOCK_STREAM: a socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6) */
/* IPPROTO_TCP: the Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter is SOCK_STREAM */
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/* sockaddr_in: the sockaddr structure varies depending on the protocol selected. Except for the sin*_family parameter, sockaddr contents are expressed in network byte order */
sockaddr_in localaddr;
/* set up the sockaddr_in structure */
/* AF_INET: the Internet Protocol version 4 (IPv4) address family */
localaddr.sin_family = AF_INET;
/* htons(): the htons function converts a u_short from host to TCP/IP network byte order (which is big-endian) */
localaddr.sin_port = htons(8888);
/* INADDR_ANY: on Windows XP and earlier if the string in the cp parameter is an empty string, then inet_addr returns the value INADDR_ANY */
localaddr.sin_addr.s_addr = INADDR_ANY;
/* bind(SOCKET s, sockaddr *name, namelen): the bind function associates a local address with a socket */
bind(server, (struct sockaddr*)&localaddr, sizeof(sockaddr));
cout << "wait for connection from the client..." << endl;
/* The listen function places a socket in a state in which it is listening for an incoming connection */
listen(server, 1);
sockaddr_in address;
int size = sizeof(SOCKADDR);
/* accept(SOCKET s, sockaddr *addr, *addrlen): the accept function permits an incoming connection attempt on a socket */
client = accept(server, NULL, NULL);
cout << endl << "connect successfully!" << endl << endl;
/* _beginthread: create a thread */
_beginthread(&mythread, 0, NULL);
char message[max_length_message];
while (1) {
gets(message);
cout << endl;
/* send(SOCKET s, char *buf, len, falgs): the send function sends data on a connected socket. */
send(client, message, sizeof(message), 0);
}
return 0;
}
output.cpp(原本想实现对话框的输出的)
#ifndef __OUTPUT_H
#define __OUTPUT_H
#include <iostream>
using namespace std;
backgroundColorChanger.h
#ifndef __BACKGROUNDCOLORCHANGER_H
#define __BACKGROUNDCOLORCHANGER_H
#include <windows.h>
void change_color() {
system("color F9"); // the blue words and the white background
}
#endif
客户端:
main.cpp
/* chat online tool client */
/* the side of sent a connection message, for instance, the ip */
/* if the project has a linking error like follows:
undefined reference to `inet_addr@4'
undefined reference to `gethostbyname@4'
undefined reference to `WSAGetLastError@0'
undefined reference to `inet_ntoa@4'
undefined reference to `WSAStartup@8'
undefined reference to `inet_ntoa@4'
undefined reference to `socket@12'
undefined reference to `htons@4'
undefined reference to `bind@12'
undefined reference to `listen@8'
undefined reference to `accept@12'
undefined reference to `recv@16'
undefined reference to `send@16'
undefined reference to `shutdown@8'
undefined reference to `closesocket@4'
undefined reference to `closesocket@4'
undefined reference to `WSACleanup@0'
the solution is setting the project links -> extra linking options -> input"-lwsock32"(on a compiler) or add "-losock32" when compling on Linux
*/
#include <iostream>
#include <sys/types.h>
#include <Windows.h>
#include <process.h>
#include <winsock2.h>
using namespace std;
/* the self header files */
#include "backgroundColorChanger.h"
#define max_length_message 10000
SOCKET client;
void mythread(void * param) {
char buffer[max_length_message];
while (1) {
if (recv(client, buffer, sizeof(buffer), 0) <= 0) {
cout << "The server connection is interrupted, please quit..." << endl;
break;
}
cout << endl << "Nightonke_Server: " << endl;
cout << "---" << buffer << endl << endl;
}
}
int main() {
/* pre_do */
change_color();
WSADATA wData;
WSAStartup(MAKEWORD(2, 2), &wData);
client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
char IP[15];
while (1) {
cout << "please input the server's ip: " << endl;
cin >> IP;
sockaddr_in target;
target.sin_family = AF_INET;
target.sin_port = htons(8888);
/* inet_addr(char *p): the inet_addr function converts a string containing an IPv4 dotted-decimal address into a proper address for the IN_ADDR structure */
target.sin_addr.s_addr = inet_addr(IP);
if ((connect(client, (struct sockaddr * ) &target, sizeof(target))) == SOCKET_ERROR) {
cout << "connection error, please input the server ip to try again: " << endl;
} else {
break;
}
}
/* the original code by another coder
ADD:cout << "please input the server's ip: " << endl;
cin >> IP;
sockaddr_in target;
target.sin_family = AF_INET;
target.sin_port = htons(8888);
target.sin_addr.s_addr = inet_addr(IP);
if ((connect(client, (struct sockaddr * ) &target, sizeof(target))) == SOCKET_ERROR) {
cout
goto ADD;
}
*/
cout << "connect successfully! Now let's talk!" << endl << endl;
_beginthread(&mythread, 0, NULL);
char message[max_length_message];
while (1) {
gets(message);
send(client, message, sizeof(message), 0);
}
return 0;
}
backgroundColorChanger.h
#ifndef __BACKGROUNDCOLORCHANGER_H
#define __BACKGROUNDCOLORCHANGER_H
#include <windows.h>
void change_color() {
system("color F9"); // the blue words and the white background
}
#endif